Skip to content

Instantly share code, notes, and snippets.

@connorjclark
Last active September 9, 2024 04:01
Show Gist options
  • Save connorjclark/4a29fbaaca79d0044694ee65dfd4f78e to your computer and use it in GitHub Desktop.
Save connorjclark/4a29fbaaca79d0044694ee65dfd4f78e to your computer and use it in GitHub Desktop.
3.0-so-far.md

Note: there is some overlap in changes w/ 2.55.x branch, due to bug fixes and minor features being cherry-picked.

Updated: sep 8, 2024

Features

  • Allow disabling resizability of windows (setting in launcher only) 6937ef2e2
  • add burn-based light radii for items, to change the glow radius when lit on fire. 6cc9ab347
  • SCC for 'Trigger Combo Copycat', allows triggering a triggers-tab copycat index bcf7b98ce
  • add 'Script1'-'Script10' shield blockflags, to block specific scripted weapons. b9e6136eb
  • LW_REFARROW, LW_REFFIRE, LW_REFFIRE2 (reflected arrows, fire, fire2) e3b23aa7d
  • Slidy Ice for the Player a923d5c42
  • option to disable transparent darkrooms stacking multiple transparent layers d9d3ac8e4
  • 'Toggle Darkness' trigger flag (toggles current room being a dark room) ff6c8151e
  • 'Req. Darkness' / 'Req. No Darkness' trigger flags; act as conditionals on a room being dark or not dae41c8c7
  • Trigger flags relating to LItems (map,compass,etc) 42b835781
  • Trigger options relating to tinting the palette 4917cea2d
  • Trigger options relating to changing palette and wavy/quake vfx 9220affe4
  • Trigger options relating to status effects and 'Push->' timing 3ee3da857
  • ZScript arrays now are separately typed from non-arrays. cf2769fe9  

    Array types can be declared by adding [].

  • add 'Note' item wizard, notes can play relative strings now e18d24342
  • add enemy flag to control if affected by "Kill All Enemies" 396c87a6a
  • add option to use the native OS dialog to select/create files e418d7124  

    A new button allows using the OS dialog to select/create a file. This can be used directly by setting the Native File Dialog option in the launcher.

  • add Cure Shield Jinx to bottles 184674728
  • add shield effect for jinxes, update Whisp Ring 97688da50  

    Jinx enemies (aka Bubbles) can now impact shields, and whisp rings now correctly apply to temporary jinxes.

    See docs/enemies.txt for how to configure Jinx enemies.

  • add shield jinx removal as refill effect (#938) 977e72321
  • add Shield Jinx trigger (#941) 985904538
  • expand palette from 6-bit to 8-bit color 4fccd7565  

    The RGB channels for colors have been increased to full RGB color range of 0-255, rather than 0-63. This increases the number of possible colors that palettes can use by 64x.

    This also impacts how colors are declared in ZScript, such as for Graphics->Tint, Graphics->MonochromeHue and combodata::TrigTintR/G/B. A script compat QR is added for existing quests that use 6-bit colors.

    A minor side effect of this change that applies for all quests is that palette effects, such as the fade in/out screen transitions and the death animation, are now smoother as there are more possible colors to animate through.

  • configurable charge step for enemy rope walk style (#953) 3fcbd09c6  

    If "Walk Attr." (aka misc attribute 10) is >0, enemies with the "Rope" walk style will use that custom value for the charging step.

  • use allegro 5 for DUMB tracker audio (mod, it, s3m, xm) d11af4e67  

    The listed tracker formats now support setting loop points in the DMap Music tab, including setting the speed / position in ZScript. Note, the only enhanced music formats that do not support these features now are: spc, gbs, vgm, gym, and nsf.

    This also happens to fix an issue where tracks that have builtin loops were incorrectly playing silence before looping.

  • add configurable weapon sfx to enemies (#977) e71f8dc99  

    This can also be configured in ZScript with npc->WeaponSFX and npcdata->WeaponSFX.

  • support delete keyboard shortcuts for most text controls 757c19430  
    • Ctrl+Backspace (Mac: Opt+Backspace) - deletes from cursor to next word boundrary
    • Alt+Backspace (Mac: Cmd+Backspace) - deletes from cursor to beginning of the line
  • fully configurable enemy weapons (#984) 36f92c7bf  

    The enemy editor now allows you to configure additional things for the weapon that the enemy fires. These used to be hardcoded based on the weapon type, but now all these are configurable per-enemy:

    • damage
    • speed
    • block flags (ignores player defense / shields / reflectable)
    • movement flags (gravity / pitfalls / drownable)
    • tile size and hit / draw offsets
    • burning sprites and light radius

Player

  • add option to disable title music 9256d13d9
  • optimize zasm scripts 16da940b1  

    First thing when loading a quest the ZASM scripts will undergo optimizations. Most optimization passes apply improvements similar to that which have been implemented in the zscript compiler, but are not present in older quest scripts. Others are novel and improve even modern zscript compiler output.

    Savings for a few quests:

    • Stellar Seas - 163762 ops (5%)
    • Yuurad - 604668 ops (4%)
    • Umbral Cloud - 105994 ops (8%)

     

    The optimizations done currently are:

    • Removing unreachable blocks of code
    • Replace many PUSH/POP with equivalent single PUSHARGSR/POPARGS
    • Reduce ops used for conditionals (COMPARER)

     

    This is on by default, but can be disabled with [ZSCRIPT] optimize_zasm = 0 in zc.cfg.

  • add zasm optimize_setv_pushr f2dd0314e
  • Custom mirrors can 'block' instead of reflect per-direction d3f813f6f
  • optimize comparison commands in ZASM 419aac804
  • optimize scripts just before use, instead of all upfront bf32e9105
  • in optimizer, consider the null D5 register when combining commands like POP 0c5bc072b
  • optimize old scripts LOADI to LOADD 1d7fa6a48  

    This removes ~8% of commands from Yuurand, ~12% from Nargad, and ~14% from Stellar Seas.

  • optimize useless stack push/pops in old scripts a273d27c3  

    This saves 15% of instructions for Yuurand.

  • add simple titlescreen, and remove music from save select screen a593e7571  

    This also reintroduces the skip_title option in the launcher.

  • remove dead ZASM 0faa3c2b6  

    ZASM ops that write to a register but never use the result are now removed.

  • continue ZASM comparison reduction even on LOAD D2 e20f62d4d  

    At some point this was necessary, but not anymore.

  • improve inference in optimizer simulator, and handle POP better 0a7117ba2
  • improve ZASM comparison when subsequent block reuses D2 cac709f3d
  • optimize SETR PUSHR to just PUSHR 442921171
  • optimize zasm pass converting to new function calls d40c0d634  

    Replaces older GOTO/GOTOR and GOTO/RETURN with more succinct CALLFUNC/RETURNFUNC.

    This saved ~2.5% of instructions in Yuurand, ~4% in Nargads Trail.

  • optimize zasm by inlining functions 86edb55fb
  • optimize old scripts STOREI to STORED da7113489
  • option to show game time in the corner, for all those speedrunners out there 9d50c5687
  • optimize LOADD/STORED to new LOAD/STORE to remove divisions d8a7872c8
  • optimize zasm by removing intermediate registers dddd96cf1  
    • For example, SETR D3 LINKX ; TRACER D3 becomes TRACER LINKX
    • Also attempts to avoid pushing value to stack just to pop later, but only if the value of the register is unmodified in the original code between pushing and popping from the stack
    • Only occurs if the register is read once. If read twice, the overhead of calling get_register is too great so it would be worse to call multiple times. Data registers are much faster to access.
  • 'Toggle Lights' cheat works on new dark rooms 1f74bdc0a
  • add opt-in automation for uploading replays 36f5d0810  

    When enabled, once a week replays are uploaded to a server when the program exits. Only replays of known quests from the database are uploaded. There is also an option to manually trigger this process rather than enabling it automatically.

    Please consider enabling this, as it greatly helps out with development by allowing us to prevent bugs. This is important for any new features we add, but extremely so for the upcoming Z3 scrolling overhaul.

    See docs/replays.md for more information about the replay system.

Editor

  • Merge 'Favorite Command' and 'Hotkey' systems 47617f7ad  

    Any 'Hotkey' can now be set to a favorite command, and all old favorite commands now have 'Hotkey's. Favorite command buttons will clear upon this update, as the configs have changed.

  • save backup when qst was last saved in a different version of zc d9a81183a
  • Add warnings to combo editor (can detect problems and warn you about them) e201fcb8a
  • Hotkey cheatsheet, open with Shift+? a49173623
  • 'Adv. Paste' string editor rclick option bd40c292c
  • Advanced Paste for Item Editor 138b58626
  • 'Warp Back' rclick option to reverse after following a warp 8dd981f27
  • Item Wizard (Shields) f30dd7095
  • assign 'notes' per-screen (just for editor use)

      Relevant changes:

    • feat(zq): 'Set Default' button to set default editbox colors e9e8b112d
    • feat(zq): 'Goto' button in 'Browse Notes' to go to a notes' screen 9bd560f93
  • support multiple palettes in map preview/image export 7d9baa655
  • various updates to default.qst (File->New) e166b7a88  
    • Add sideview swimming tiles
    • Add charge-swimming sprites
    • Add Bunny Link - this required expanding the pages per LTM from 1 to 2
    • Add BS/Z3 swimming tiles
    • Add the missing enemy tiles from Outlands
    • Magic Pols Voice now uses CSet 10, to make room for ...
    • Add Whistle Pols Voice: blocks arrows like a Magic Pols Voice, but is a One-Hit Kill via the whistle. Uses CSet 7
    • Improve the lifting and holding sprites
    • Improve Z3 Octorok tiles (Slow Fire and Bomb Octorok)
    • Update credits on page 109
    • Convert Bug Net to use 4-bit colour
    • Fix enemy bombs using CSet 6
    • Delete unused scripts in the tiles
    • Delete unimplemented Sprite 088 (Firework)
  • set test_mode_record option in test dialog directly cfc107738
  • export/import strings to .tsv text file 13e56e789  

    Allows for exporting strings to a spreadsheet, text editor, or other program for modification, then importing them back to ZC.

    The first row of the .tsv (tab separated values) file are the column names, followed by an example row to designate where the first three lines begin and end for each string (but you can add more lines than that).

    For best results in a spreadsheet, "Freeze" the first two rows and use a monospace font for the "message" column.

    Example: https://docs.google.com/spreadsheets/d/197-NSvNQJ174Ri9GVlxYDX4oFp8w1SZbmOXuDohKZZk/edit?usp=sharing

  • fix some tiles in default.qst (File->New) 9add7e25f  
    • Fix wrong assignment of lava drown tiles
    • Delete redundant diving tiles in Z3 player tile pages
  • ffc editor now previews large ffcs a3cf09ddc
  • show CSet in combo pages c2029cafd
  • hex entry for string control code dialog 57a0d35bb
  • add help text to the FFC editor (#973) a4030cac3

ZScript

  • more value range types (.., =.., ..=, =..=) 1e5be558a
  • allow mathematical range expressions [A,B) etc 61c5ccc92
  • range loops (loop(int q : 0=..10))

      Relevant changes:

    • feat(zscript): range loops can contain variables in ranges/increment, and negative increments cb583e1c4
    • feat(zscript): range loops have '@NoOverflow()' annoation, docs ded10db59
  • allow multiple comma-delimited increment statements in for loops ab8232c78
  • allow enums of non-int pre-existing types (ex. long) 9ca034ea1
  • add networking via websockets 41c3622a4  

    WebSockets allow for scripts to communicate with an external WebSocket server. This introduces an official way to use the network in ZScript.

    The following example script communicates to a freely hosted WebSocket server, which simply responds back with the messages it receives.

    To make your own WebSocket server, Python is a good option. Some example libraries:

     

    #include "std.zh"
    
    generic script WebSocketScript
    {
       void run()
       {
           printf("Connecting to websocket.\n");
           websocket ws = Game->LoadWebSocket("ws://ws.ifelse.io");
           ws->Own();
           bool hasSentMessage = false;
    
           while (true)
           {
               if (ws->State == WEBSOCKET_STATE_CONNECTING)
               {
                   Waitframe();
                   continue;
               }
               else if (ws->State == WEBSOCKET_STATE_CLOSED)
               {
                   char32 error[0];
                   ws->GetError(error);
                   printf("Failed to connect: %s\n", error);
                   break;
               }
    
               if (ws->State != WEBSOCKET_STATE_OPEN)
               {
                   printf("Failed to connect: %l\n", ws->State);
                   break;
               }
    
               if (!hasSentMessage)
               {
                   printf("Connected!\n");
                   ws->Send("hello world!");
                   ws->Send("domo arigato!", WEBSOCKET_MESSAGE_TYPE_BINARY);
                   hasSentMessage = true;
               }
    
               while (ws->HasMessage)
               {
                   int message_ptr = ws->Receive();
                   int type = ws->MessageType;
                   if (type == WEBSOCKET_MESSAGE_TYPE_TEXT)
                       printf("got text message: %s\n", message_ptr);
                   else if (type == WEBSOCKET_MESSAGE_TYPE_BINARY)
                   {
                       int len = SizeOfArray(message_ptr);
                       printf("got binary message of length: %d\n", len);
                       for (int i = 0; i < len; ++i)
                           printf("%d: %l\n", i, message_ptr[i]);
                   }
                   else
                       printf("got message, but with unknown type: %l\n", type);
               }
    
               Waitframe();
           }
       }
    }
  • 'atol' (string to long) 475cac6ce
  • add template types to some internal functions 633d75471  

    The following internal functions have switched from using untyped to template types:

    void ArrayPushBack(T[] arr, T val)
    void ArrayPushFront(T[] arr, T val)
    void ArrayPushAt(T[] arr, T val, int index)
    T ArrayPopBack(T[] arr)
    T ArrayPopFront(T[] arr)
    T ArrayPopAt(T[] arr)
    void ArrayCopy(T[] dest, T[] src)
    int SizeOfArray(T[] arr)
    void ResizeArray(T[] arr, int sz)
    void OwnArray(T[] arr)
    void DestroyArray(T[] arr)
    
    void printfa(str* format, T[] args)
    void sprintfa(str* buf, str* format, T[] args)
    
    T Min(T arg1, T arg2, ...T rest)
    T Max(T arg1, T arg2, ...T rest)
    T Choose(T arg1, ...T rest)

    This means that the type T must match other occurrences of T throughout the entire signature, given the types of the parameters used by the callsite. For example, this code no longer compiles:

    printfa("hello %d", 1) // Second param is not an array
    Object objects[] = {new Object()};
    ArrayPushBack(objects, 1) // Second param is not an Object
    int v = ArrayPopBack(objects) // Cannot convert Object to int

    Note: for now, SizeOfArray and ResizeArray still allow char32 for their array parameters, since that is common for string operations and we don't have a formal string type yet.

  • add garbage collector for automatic memory management d4bc547f8  

    Objects created by scripts are now automatically deleted when they are no longer reachable from any script.

    This removes needing to manually delete objects you create (either with the delete operator or Free()), and mostly removes any reason to ever call Own().

    See the new "Object Memory Management" section in ZScript_Additions.txt for further details.

  • option 'OLD_ARRAY_TYPECASTING' to use old array type handling d7555bf9e
  • add LEGACY_ARRAYS option as more lenient approach to array syntax caeb93357  

    This replaces the OLD_ARRAY_TYPECASTING option with LEGACY_ARRAYS. It can be set to on, off, or warn, and defaults to warn. This option supports usage of deprecated syntax for arrays. This will continue to work:

    int arr = {1, 2};
    Trace(arr[0]);
    
    • by default, this will warn that int[] arr is the preferred syntax
    • legacy arrays syntax is currently not allowed for objects that must be free'd, such as custom classes or bitmap (but, for example, lweapon is fine)

     

    Additionally but independent of this option, parameter types are cast to/from arrays when resolving a function call. There was an existing feature that selects the function that required the fewest type casts, and this taps into that. For example, this code works:

    void fnArray(int[] arr) {}
    void fnLegacyArray(int arr) {}
    
    ...
    
    int legacy_arr = {1};
    fnArray(arr); // arr is cast to int[]
    int arr = {1};
    fnLegacyArray(arr); // arr is cast to int
    
  • 'TileBlit' and 'ComboBlit', for drawing parts of tiles/combos c874bc20e
  • webapp for exploring and sharing ZScript ae2a67e77  

    https://web.zquestclassic.com/zscript

Visual Studio Code Extension

  • document symbol outline, hover tooltips and "Go to Definition" dbd473b97  

    This patch greatly enhances the capabilities of the language extension. New features are:

    • A symbol outline of the current script, showing all variables, functions, classes, namespaces, etc.
    • Tooltips on hover, shown if a variable/class/whatever was declared with a comment. This supports markdown
    • "Go to Definition" to jump to where something is defined. You can right-click to see this option, or CTRL/CMD+click on something
  • support @link tags in hover tooltips 1430272d2  

    Comments may contain inline links to other symbols with the @link tag:

    // Better than {@link counter2} ... {@link counter2|that counter is lame}
    int counter1;
    // This also works as shorthand for links: [counter1]
    int counter2;

    When hovering the mouse over any usage of counter1, the tooltip will render these as clickable links that navigate you to the specified symbol.

  • support Go To Definition for type of variable declaration 32d372e64
  • support Go To Definition for includes/imports dffa4cf41
  • support Go-To-Definition for enums c3ae6346b

ZLauncher

  • set save folder 303e3a643
  • add options for window size, and cap max default window size 919bda156  

    [ZLAUNCH] window_width, window_height in zcl.cfg

    Cap max default size to 2x

Web

  • first pass on wasm JIT backend for web 08254299c  

    Adds a new backend to convert ZASM to WebAssembly. This also includes some utility methods for analyzing the structure (finding the functions) and control flow of a ZASM script, which was necessary to split ZASM scripts into multiple WebAssembly functions and implement the control flow of a ZASM script into WebAssembly structure control ops.

    Although prime.zs is ~10x faster, scripts from real quests aren't any faster than the normal ZASM interpreter, since a very naive and poorly performing method was used to transform the ZASM control flow graph.

    The utility methods for analyzing ZASM should be useful for improving the x64 backend too, for example, to similarly compile only one function at a time.

  • support more ZASM ops for wasm jit 53d5bc9a7
  • support new SETCMP, GOTOCMP, CALLFUNC, RETURNFUNC ops in wasm 1c190a5a7

Bug Fixes

  • prevent clock shifts from hanging the program bdb8a1819  

    Allegro 5 doesn't use a monotonic clock that ignores suspended time, so day light saving shifts or even hibernating your computer can result in Allegro trying to do so much work to "catch up" that it hangs the program. See liballeg/allegro5#1511 for more.

  • shift key input no longer accidentally ignored d46eee890
  • passive (non-button) items not respecting "Usable as a Bunny" flag 30ebe5386
  • ZScript metadata fields cutting off at semicolons in strings 0f37a4b8a
  • 'box_out' popups sometimes appearing squished in the upper-left 8f3d6f8ec
  • use correct app id in zalleg_setup_allegro 41139dde1
  • default bs patra has broken animation 38d90c960
  • newer hero movement ladder polish 09cc6c5eb
  • being able to carry objects while swimming, when lift glove isn't swim-capable 4f6e3a1a5
  • 'Push (Generic)' combos not properly locking into place on block triggers 651ccef1c
  • fairy npc not despawning when picked up ea1be60e0
  • deleting subscreens resulting in invalid/crashy data f0d8830a0
  • arrow key navigation in menus not resepecting hidden items 5046e239f
  • prevent 1.90 qst load compat from setting first dmap cont/compass to bad value 81cd619e9
  • ZScript access to subscreen elements was missing a 'transparent' color option f415f53ed
  • zasm metadata not clearing properly when assigning slots c090dee25
  • implement set volume for GME music (spc,gbs,vgm,gym,nsf) 74d24c557
  • Enemy Flames not reflecting off of shields, even with reflect flag set 3ea00017a
  • issues with numbers between 0 and -1 489b85ea7
  • swords not updating properly, sometimes 2986883e6
  • old quest subscreen minimap titles overlapping aedf6f0bb
  • placing flags on layers not marking the layer screen as "valid" 68fc92a3c
  • ensure file is closed when qst fails to load 621d6d1f8
  • changer ffcs counting for trigger groups and similar effects (they shouldn't) 1a1bd37ac
  • retain monitor resolution for fullscreen mode 9b103f078  

    Previously, the maximum monitor resolution would be used when using fullscreen mode. That was bad because it messes up the window layout of anything else on that monitor. Now we create fullscreen displays without changing the resolution.

    Also, no longer destroy and recreate the display to change fullscreen/windowed mode. Switching between is much smoother now, and the code got a bit simpler and safer.

  • zfix modulo operator being entirely wrong efe612523
  • changer ffcs counting for trigger groups and similar effects (they shouldn't) 7ce5862b6
  • zscript docs were not being generated for release package a5a9bc81d
  • generic script InitD[] not working at all 5732b531b
  • increase sfx buffer to prevent "Out of buffers" log spam e7c214eb6
  • Improve dropdown numerical search c729bb682
  • reduce sfx buffer to decrease lag caused by e7c214e 803871558
  • update 'default.qst' 4e1bd29e4  

    Several default subscreen fixes (some by P-Tux7, some by myself)

  • 'Screen->Lit' not compiling; now properly returns (and sets) screen's lit state 8f50a32f5
  • removed flag that was breaking mod playback 5dd03e998
  • correct the version string for 2.55.x releases 7d9ceee14
  • incorrect default right string margin 1428ca004
  • remove sfx limit (except for fuzz testing) 0c1de2949
  • initial path not being set for file dialog 1d08708c9
  • avoid crash when loading midi using native file dialog a038d2250
  • capture allegro 5 systems logging in allegro.log fb0b53f23
  • sprite drawing not deleting all bitmaps it created 471351e03
  • crash in native file picker from bad string a23f8ff68
  • crash when file prompt initial path has no slash 9df104fd9
  • improve key input latency by simplifying d_vsync_proc d97e0673d
  • call allegro_exit before exit to avoid rare hang seen on linux 4eff6312a
  • generate correct version string for 1.92 quests 52dc20365
  • ctrl+a,c,v work again in text fields 5abb1d963
  • prevent crash when deleting all text in some input fields d989ec304

Player

  • Music not properly changing when using some warp types (ex. SCC warp) 0a1d27ffa
  • extra pushing allowed per screen cb1d50987
  • cheats menu being greyed out when it shouldn't be b0db6567a
  • improve main menu responsiveness 7fb3e48ff
  • new respawn points not accounting for dmap offset c6578d8a4
  • initialize fadevolume to avoid undefined behavior 61d038072  

    This fixes a bug where music would randomly be silent or extremely loud.

    Also, cap the volume used to play music to 255, to avoid ever playing it so loud again.

  • set volume correctly when music changes with only fading in or out b30434eb0  

    For example, if the new music has a fade in frame duration of 0, and the old music has a fade out frame duration of >0, then the new music would incorrectly have its volume stuck at 0%.

  • menu bar unaligned with dropdown due to menu using int scaling 237ac670e
  • Swim speeds not being saved to save file 02beb5d87
  • spotlights with color setting '0,0,0' or tile setting '0,0' now function 5b6052c39
  • Allow throwing lifted object without validating cost 9085badf6
  • system menu not closing on reset/quit/etc 926608eab
  • thrown weapons now should hit enemies that they land on 0d64e0240
  • all 'break on landing' weapons should hit enemies/the player that they land on 7442707be
  • correctly make qstpath relative to quests dir in "custom_game" dialog 2e9e1302b
  • use correct sav path for -standalone mode 742115e11
  • fix 'warp' SCC sometimes not closing the string 546e73659
  • prevent bad module path being set after exiting 6b57af398
  • use more performant throttleFPS instead of rest in system menu 4c9ace43b
  • remove accidental double compilation for global scripts 1648daea9
  • draw to correct bitmap when showing button clear prompt 44bf4b63d
  • minor replay determinism bug for subscr_item_clk (selector animation) 0044365b3
  • only assign save path just before actually writing to disk 17ba9ef42
  • call saves_do_first_time_stuff when changing slot qstpath 0b7036d74
  • handle edge case when changing unplayed save file qst 3dfbf7b61
  • prevent calling dmap script twice in scrolling dmap warp 6fc179786
  • set previously unset save_t write_to_disk in all places 34d840c30
  • not showing error dialogs in title screen, and unbreak -only switch 949bb6abe
  • clear spin state during screen scroll 23a9466d4  

    This avoid a ghost sword visible during scrolling, and also prevents a nasty bug where the player's action state would be frozen until hit.

  • prevent crash in save creation by resetting global vars 9d9ea42c2  

    When a game is loaded, many global variables are initialized to a known state. These variables were not reset when the game ends and returns to the title screen. However, save creation happens to call code that checks the active subscreen pointer, which was invalidated. Accessing this could randomly crash or corrupt the program.

    Now, these global variables are reset also just before loading the title screen.

  • prevent failing to save after continue e2922a7d3
  • lift glove 'disable item use' not stopping sword SFX from playing 34a26817d
  • disable scripts that start with an unknown command 4aa4acd94
  • check for null when printing ZASM command string arg 6c4d774c5
  • improve function breakdown in structured zasm 68259bbf4
  • handle first command being function call for structured zasm 69bbf846a
  • handle recursive function calls in ZASM cfg creation 1649a62e1
  • detect dtors as separate functions in structured zasm 08e17d01d
  • remember last save slot position when returning to save select screen b05607e2e
  • [win32] invisible hero because of MSVC bug 1c92f8d89
  • remember cheat on continue game c82beb899
  • 'Custom Weapon' itemclasses rounding down step speed b8812a72c
  • re-optimize when jit reuses scripts from last load f55cf241f
  • restore option to scale display to full window size 61ff78f20  

    This broke when the display was fixed to only show at the correct aspect ratio. Default is still as before, but now the "Force Integer Values for Scale" option works again.

  • still allow for game area to be stretched, ignoring aspect ratio 5a641ebce
  • ignore gamepad input when window is not active b355cfed6
  • weird newer movement edge-case 1dcaa2a4c
  • opening spacebar map triggering some secret effects on the current screen 9baf8d694
  • lens unintentionally making enemies sometimes invisible 5de1f0c26
  • lens unintentionally making enemies sometimes invisible c81d068a6
  • crash when running replay without any real saves a9d6f4c44
  • Divine Escape particles sometimes flying in wrong directions 1ea90d59b
  • invalid optimization on broken SDDDD register d482c135b
  • disable propagate_values and dead_code passes for now cca0aaf0d  

    These are likely to have a few edge cases remaining.

  • remove unnecessary absolute path check for standalone mode saves 8f2e35bd0
  • show final game frame when opening/closing subscreen 89a0cd84d  

    For older quests utilizing none of the QRs related to "cool scrolling", the subscreen open/close crawl would show a version of the game frame that was missing a few things, like enemy or player sprites.

    This should allow us to simplify the rendering (no need to render most things twice to a secondary bitmap), and just looks better.

  • do not stretch GUI ad7995cf1
  • set default volume to 100% instead of 25% 297e7b933
  • skip title screen if specific save slot is given 94f39f26e
  • tall grass on layers not applying its sfx/sprite 70d9abedf
  • fix snapshot with NOSUBSCR not supplying a palette and not accounting for NOSUBSCROFFSET a9b90ffea
  • prevent grid aligning while jumping, which broke jumping for some old quests 53db0b855
  • for replay mode, whistle sfx pauses game for number of frames proportional to sfx length instead of 0 frames ed5921c9c
  • hero action "swimhit" incorrectly unset due to broken isSwimming() check 192a9fa64
  • combo cycling reset too early for animations with frame skips 61fc1edcf  

    Turns out this never worked properly!

  • defer deletion of sprites to end of animate logic 7a9cb4a11  

    This fixes a crash caused when a sprite deletes itself in middle of its animate logic.

  • prevent OOB access for darkroom ditherrectfill a5f01cd25  

    When scrolling, this function could be told to grab a line of the bitmap memory outside its bounds, which resulted in a crash.

  • reset global variables on continue game for replays eec8456ce
  • actually stop mp3/ogg, and explicitly stop title music c3f7ec46f  

    The titlescreen music would restart in the file select screen if the Sound dialog was opened then closed. This was because the volume was set to 0 to fade out, but it was never actually stopped.

    But also, due to a bug ogg and mp3 formats were really just "paused" when told to stop, so setting the volume afterwards would result in resuming music that was meant to be over.

  • ambient/background sfx volume not being set 556124969  

    The recent removal of "digi_volume" made all background sfx play at full volume. Fixed that.

    Additionally, fixed a bug in the sound dialog what skipped the first sfx when adjusting currently playing sounds to the new volume. That first sfx is often a background sfx.

  • inline function optimization handles PEEK correctly a3d768e8f
  • various fixes to optimizer that broke crucible quest 47ca63d08  
    • ignore QUIT in inline opt
    • handle POPARGS in inline opt
    • add missing register dependencies for multiple commands
  • inline function optimization handles PUSHARGSR correctly ffd3fe1fe
  • various slope improvements, like fixing ffc slopes a93568375
  • fix mirror shield not resetting the last used mirror combo position 255151b81
  • save select screen not showing new hp after save->reset e91c347a8
  • load default quest for sfx when loading replay 0586712df  

    Quests before custom sfx rely on the default quest providing sfx, but that wasn't being loaded when playing back a replay. So it would either use whatever the last quest loaded, or have nothing, which was the case for the replay test script.

  • use correct graphic when holding up purchase from bottle shop 00fae2c4c
  • apply BS swim sprites compat rule to Zelda 3000 qst a4028258e  

    This QR is applied to all 1.90 quests, but Zelda 3000 was saved in 1.92 and this visual bug was overlooked.

  • consume button presses in subscreen menu be48e2fb0  

    The subscreen refactor ~6 months ago resulted in button presses not being eaten. One side effect of this was the item selection sfx playing for every frame the button was down, instead of the intended one time.

  • ZC menu options render/get disabled correctly db63ab1f8
  • improve replay stop process for update mode f21bed939
  • websockets reading wrong pointer f98c49c69
  • check if save slot is valid before loading 9651948a2
  • fix crash in Options>Snapshot Format 91f0fb028
  • 'Spotlight' combos on changer/ethereal ffcs still shooting light 99d4786b9
  • fix buggy color flickering on big player sprites 5a6bf306e
  • hardcode 120 for zscript alpha register d23a9bdd1  

    This fixes some quests that only look at the alpha version and, seeing it was now 0 presented an error message to the user.

  • some variables being improperly reset on 'Continue' 7cfededaa
  • bug in dead code optimizer when register is both read and written to 2ed2cd56d
  • visual text bug in sound panel 5f16c4d04
  • active shields interacting with light beams while inactive 96aeccbc5
  • reset playing_field_offset at beginning of scroll 5a520f4d4  

    This prevents the draw offset from a quake from persisting during a scroll.

    See https://discord.com/channels/876899628556091432/1238226802867048529

  • passageways can have their own midi music (#934) 97a0c0130
  • npc scripts for many enemies ending after one frame 733263500  

    Enemies larger than one tile use a different code path than other enemies, and that path was mistakenly only allowing scripts to run for a single frame.

  • kill all sound effects for passageways, item cellars, and when stepping out of a warp (#942) 9f699e76c
  • [windows] save path being cut off in log bbe76c4fb
  • resolve replay qst against quests dir, handle missing file better 95dc9e97a
  • prevent replay save from happening on title screen fde75056d
  • also save replay when selecting Quit Without Saving 7efaac166
  • shadows for rocks and boulders not drawing (#951) dc7454ec5
  • side shield flags on npcs being flipped when facing left/right 04063b574
  • Damage combos with Custom Damage not working on FFCs 512658280
  • correctly restore sword/potion/triforce items with fairies in pre-2.55 quests cb0124c5d
  • restore palette after wavy effect 7ad5419bf  

    The wavy effect was leaving the palette slightly off what it should have been, which was making the colors slightly saturated until the next time the palette changed.

  • draw decorations correctly during scrolling ba60e60f2  

    Some decorations (like combo sprites) are drawn without the correct offset during screen scrolling, and worse were not disappearing after the end of the scroll (not until its animation naturally finished). Now these decoration sprites are drawn correctly during scrolling, and get removed.

  • do not ignore replay forever if save has not been played yet 589dd548c
  • lockblocks on layer 0 no longer ignored in cave dmaps if locked door present 05c7e0053  

    Context: https://discord.com/channels/876899628556091432/1278165595321405554

  • pause music when opening player data with cheat shortcut 8810f9a16
  • avoid crash in Go To cheat by checking destination is valid edcda9e7c  

    This cheat dialog expects you to input the screen number before any DMap xoff is applied, which can result in directing the game to load an invalid screen and crash. Now the screen is validated, and the xoff is displayed next to each DMap in the dropdown.

  • fire trail weapons glow in dark rooms, just like flames 5c3785599

Editor

  • Tile editor checkboxes not clicking 37179fef3
  • disable unpack cache to fix tile rotate/flip 64f42deb3
  • tile page rclick "insert", "delete" was swapped d84746490
  • disabling tooltips works again 7e3738d44
  • item editor candle text goof 297c0e9a2
  • 'Go' in warp dialogs not rebuilding transparency table 7e5e8300e
  • fixed warp ring dialog f77b41cb1
  • 'File->Exit' not exiting ae2ee93e5
  • wrong button focused in zscript compile dialog 861de33cd
  • tile editor bugginess 98c6fd27c
  • Polish numpick dialog, fix new gui focusing d9ced4043
  • 'Scroll to Combo' on screen rclick being offset 9e831d7fa
  • greyed out pasting in string list 887229b74
  • Crash on changing map count b79531785
  • timeout of 0 for parser timeout now acts as "no timeout" 310c8a9d1
  • create test init data relative to qst init, not base init 5563f5cd0  

    This was originally done this way to avoid changing test init data when the quest's actual init data changed, but that maybe is not as useful as the other approach.

    Also very simply fixes the problem of screen data (and other init values) not being properly set.

  • autocombo/combo pool/combo alias pages RClick menus being offset 0e01b8d78
  • 'Open Tile Page' on combos not using the ORIGINAL tile of the combo 7e35354b1
  • missing rclick menu separators 1b0b0341c
  • disable tooltips when hotkey cheatsheet is open d3ccd1c68
  • clean up several issues with the warp dialogs 4291118a4
  • options->fonts being broken/inconsistent, not saving changes adeeba4db
  • undefined memory write when applying modern quest ruleset faeaa94a3
  • lockblock/chest combo wizards not saving 'Use ExState' flag bb1899ec8
  • some more issues with warp dialogs 2afa91eec
  • warp dialogs not properly previewing negative xoffset dmap map-marked squares 0dad039a4
  • test init data not being applied correctly c599dfc30
  • midi edit dialog not showing in new rendering system 5d58ab785
  • solidity preview inaccuracies da627e7e9
  • 'Tools->Combo Flags' bugging out when clicked 112b2928b
  • crash related to 'Scroll to page' for aliases/pools/autocombos 7d0fb2ac4
  • handle quest path/title with spaces in package export 11b09ef8c
  • transparent tiles not drawing correctly in map preview b9ebc75d9
  • error message on failure to load enhanced music in the dmap editor 26e448194
  • skipy broken in combo preview animation 43b2058e2
  • combo animations not resetting after using combo selector in dialogs 96e0752b3
  • weapon type names drop down being empty ccdd2c9e1  

    This broke from recent addition of reflected arrows/fire (e3b23aa)

  • hide unimplemented enemies 16abaf626
  • handle error instead of crashing if package export fails e26e02c9e
  • 'Load Tileset' not applying compat fixes 9d7dedaee
  • stop clearing screen when editing palette b26f3ab0b  

    Since the render refactor, we haven't needed to clear the screen when changing palettes, since this dialog is rendered to a different bitmap than whats in the background.

  • minor typo in Export DMaps title 94b469569
  • correctly handle variable length title in all dmap reading/writing 3137e13f1  

    6bd8a9a added support for variable length dmap titles, but only for the main dmap reading/writing code. This functionality is duplicated across dmap import/export and other places, but wasn't updated.

  • 'View Map' favorite command skipping menu b9ea47f75
  • Crash in ZInfo menu if descriptions are long 9546a257e
  • 'Notes' and 'Browse Notes' not having menu buttons 5c338087d
  • avoid overwriting screen bookmarks on quest load 771f801de
  • 'Gen Flags' being missing from combo advanced paste 7a84cbf40
  • upgrade tile 'move' code, more things now update on moving tiles (#916) 5c29d6f4e
  • crash on reducing map count e061ad48b
  • crash on moving combos in quests with many maps/screens 80af019ef
  • Improve efficiency of combo moving + fix crash + fix 'undo' combo move 4efe6b07d
  • Improve efficiency of tile moving + fix 'undo' tile move 7b26369e0
  • warp dialog selector mishandling negative dmap offsets bc0c7ac8e
  • memory issue when moving/inserting tiles/combos 3c72e3712
  • arrow buttons above combo columns sometimes not working properly 1af434da4
  • "Used Tiles" completely failing to calculate 009d59164
  • 3-stair warp dialog not properly listing catchall purpose 6ab8d137e
  • death/spawn sprites not properly updating on tile move a164a6cdd
  • prevent invalid string access resulting in crash aaa65c22c
  • buffer overflow in info editor dialog 63b6cb23f
  • [windows] Load Tileset with native file dialog no longer busted 408b83815
  • wording consistency issue (trigger should refer to the Triggers tab) 4468501f9
  • some number entries (using SWAP_ZSINT_NO_DEC) being broken. 277c541d5  

    Notably fixes many spots in the "Insert SCC" dialog, and some in combo wizards.

  • mark ffc count dirty when using Paste Special > FFC 0b0c47178  

    This was preventing FFCs from being retained on a screen when using the special FFC paste mode.

  • restore proper animation speed for combos in screen view 3f5c7a036
  • prevent dmap editor crash when map is no longer valid fa665bd65
  • prevent various quest report crashes 199b3e4e1
  • set the default values for patra's (2 and 3) inner eyes eafaec18f
  • reduce latency on combo page paste when ComboProtection is off 5fd5fa503
  • prevent crash when assigning global scripts 143e6836c

ZScript Standard Library (std.zh)

  • clean up some missing function returns ef5211325
  • DMFS_ constants being off-by-one c0144e90d
  • 'TRIGFLAG_' constants were off-by-one at a certain point in the list 5e06d5629
  • use template for Cond to support arrays af4293cd6  

    Also deprecate and suggest using ternary expressions.

ZScript

  • 'subscreenwidget->PerContainer' not working 79a9cd530
  • al_rest crashing when using debug feature 697aca5ea
  • parser configs not working d9de1de73
  • issues running destructors 9e192b590
  • errors related to breaks in infinite loops ccf995957
  • handle rare COMPAREV2 for x64 jit fa4a23e65
  • sprintf giving a wrong error message on %c d17e8aa85
  • 'Screen->SetExDoor()'/'mapdata->SetExDoor()' not opening matching doors 886f44ed1
  • grab correct value from stack for POPARGS JIT x64 6f0b3e2a0  

    This didn't seem to break anything, but it showed up as a difference when comparing registers from JIT w/ non-JIT.

  • Hero->WarpEx not using dmap xoff when setting continue screen 419a8ddde
  • global var initializers not erroring when non-constant 15bc0daf5
  • issue with global variables sometimes not initializing properly 872162115
  • label error bug with 'while(true)' and 'break;' bfef7fd44
  • escape character " not working properly in string literals 9ad696e10
  • case-range backwards check b3fb9bc30
  • missed handling arrays for unused var trimming 8d2ddc6f9
  • a couple of small errors in recent optimizations 02bc0f4ff  

    Should fix issues with 'while(!false)', and variables declared in loops.

  • invalid character errors wrongly occurring for values 128-255 512d5b72c
  • subscreen widgets not allowing SUB_COLOR_TRANSPARENT to be used 163b7406d
  • class function params with same-name as class member not shadowing properly bbc08487d
  • class/object destructors stack being offset wrongly 56967f8d8
  • clear script data when reassigning script 03ce2a4f6  

    Previously, only FFCs properly reset their state when changing their script. All others would retain their state, so would instantly do all the wrong things.

  • compiler crash related to invalid array indeces a65faeff5
  • fix Audio->SetMusicLoop() truncating decimal values fd7497395
  • exit with correct status for jit on QUIT 3a48a0aea
  • sanity check for bitmap->isValid() and bitmap->isAllocated() b264073c2
  • stale data in destructors 99133fa5e  

    scripted objects weren't clearing data used by the destructor when being cleared, leading to future objects referencing the stale data if they didn't have a destructor of their own to overwrite it.

  • clear jit-compiled scripts as intended when loading new quest b84c8d827
  • generic script item collect event fix 5d07768c7  

    Item Collect event will no longer be fired for items such as timeout items when they are not actually able to be collected. Due to timing changes, the "Combine when collected twice" now also occurs BEFORE the event.

  • fix crash when creating too many paldatas 15355e46e
  • fix paldata->CopyCSet() referencing the wrong pointer a5e5dcca8
  • handle out of bounds for Game->LItems[] 89ca47723  

    This fixes a crash in Panolpy when reading a specific sign.

  • return enemy x,y when getting fairy item x,y 38d6fb23d  

    Setting item->X,Y on fairy items additionally sets the position of the corresponding fairy enemy sprite. However, the getter returns the item coordinate. This resulted in unexpected behavior from something harmless like item->X = item->X causing the engine fairy movement to halt.

  • consider PEEK when finding function calls for structured zasm c45c5f5e7  

    The structured zasm builder assumed all function calls are followed by POP D4 in older scripts. However, if POP D4 is followed by PUSH D4 then the compiler replaces it with PEEK D4. This oversight missed these function calls, which broke the JIT compiler and ZASM optimizations for newer 2.55 compiled scripts.

  • use correct config section for optimize_zasm 694d589f6  

    The base config was using the wrong value, so it was still always on.

  • handle WAITX not actually yielding in JIT compilers 6e95932c2  

    WAITFRAMESR D2 does nothing when D2 is 0, but the JIT compilers assume all wait commands should yield. Now they check if waiting actually occurs.

  • x64 jit compiles STACKWRITEAT correctly 5f8f9d124
  • invalid compiler output from removing unused variables d8123f886  

    The compiler has a pass to remove unused variables from taking up a position on the stack. However, a logic error made it so the wrong scopes would have their stack variables repositioned, which resulted in multiple variables sharing the same stack position, and breaking the script.

  • fix sideview sprites becoming unable to jump when on the ground 2a500a0d1
  • compat rule for old sprite jump behavior 1d95049f9
  • parser bad optimization edge-case 978ab1b63
  • parser failing to properly initialize some variables b93b1e224
  • crash in UserDataContainer, broken websocket->Free() 32996be02
  • websocket double-deleting their arrays, doing extra alloc/dealloc work 83df3a67b
  • verify first index for screen_d bbeb76cd5  

    This fixes a crash in Titan's Gate.

  • some array-related functions breaking for arrays >65535 in size f6ad9203a
  • class variables not shadowing global vars properly 46ed8bf58
  • bad optimization causing global vars to sometimes read incorrectly b000fc9e2
  • some wrong error messages related to mapdata FFC access bf68795d9
  • websocket pool being destroyed on 'cont_game()' ae375c530
  • socket arrays sometimes going invalid? 12e3b9a92  

    Patched the issue here, not the cause. Not sure what caused it to sometimes go invalid, but a validity check seems sane.

  • 'delete' within a destructor being buggy 0bb0da1de
  • disallow casting custom objects to unrelated types ed6faae63  

    A bug in type conversion allowed this code to compile:

    Object obj = new Object();
    int number = obj;
    int numbers[] = {obj};

    The above code now produces a compiler error.

  • derive language runtime version from compiled scripts a772dd873  

    The script engine checks the version a script was compiled in to vary some behavior. Previously this version was set to the section version in the qst file format, but that is updated even if scripts were not re-compiled. Now we look directly at the script metadata to set this version. This avoids issues with saving a quest in a new version without a recompile.

  • don't only show singular deprecation warnings 88898e22f
  • handle non-global objects correctly when reloading game f93172d33
  • allow simple types to match a template array type, for now 08756b8cb
  • 'Hero->Warp()' using current screen's warp return square value 1f010f2d6
  • stack offset issue when 'return'ing inside a 'loop()' dc6c35037
  • not correctly removing stale pointers on reload 4bd0e5412
  • '@AlwaysRunEndpoint("off")' erroring despite being valid 26c78ebec
  • exit process when preprocessor recursion limit is reached 58aaefd3a
  • handful of zasm commands using wrong name fd5901f67
  • Trace(string) using wrong register db2256d50
  • wrong names for zasm npc InitD and item WeaponHitWidth 00c1ec410
  • various symbols with broken compiler output 672597c11  
    • npc->Attack()
    • npc->CanSlide()
    • npc->ConstantWalk(int[])
    • npc->ConstantWalk8(int[])
    • npc->FloatingWalk(int[])
    • npc->HaltingWalk(int[])
    • npc->HaltingWalk8(int[])
    • npc->isDead()
    • npc->NewDir8(int[])
    • npc->Remove()
    • npc->Slide()
    • npc->StopBGSFX()
    • npc->VariableWalk(int[])
    • npc->VariableWalk8(int[])
    • Trace(char32[])
  • remove some unimplemented symbols and correct some types f6d59d044
  • object fields not being available in dtor 7feb9afdd  

    This regressed because of the recent GC changes.

  • compiler crashing on for-each loops b00f59aad  

    This regressed because of the recent error locations refactor.

  • some bindings ZASM using wrong literal values 975cf9c60
  • 'loop()'s not having location metadata associated with their identifier 68a5f70c8
  • 'hero' and 'link' script types not compiling 4ce3a2186
  • code gen for range loop using wrong op 213361564
  • handle engine subscreen in ScriptTypeToString 19edaac07
  • dealloc owned objects for all combos in loadscr 50a9996df  

    For some reason, only the combo at position 0 had its owned objects deallocated when loading a new screen. Now they all do.

  • 'OwnArray()' not working properly at all d706df903
  • code blocks sometimes not removing object references 2413e5ed8
  • crash from metadata of var inside if statement 54cb5c3ac
  • continue generating editor metadata after (most) compile errors 3d5912f15
  • generate metadata for code even if optimized away 8defe2955
  • scope error when using for (...){} else {} f43e46907
  • prevent bogus "invalid object pointer" caused by uninitialized memory 9db7d3403
  • scripts no longer use wrong context after many sprites created d88333f92  

    After 65536 sprites have been created without closing the player, the ID of subsequent sprites was too high for how the internal script engine stored the state for each script. This resulted in randomly using some other script's state, causing general mayhem.

  • LoadDirectory always failing due to bad path validation d864cc0f0

Visual Studio Code Extension

  • character literals not highlighting properly 5dc7bd7c0
  • 'AlwaysRunEndpoint' annotation missing syntax highlighting b5b8ef720
  • 'loop' keyword missing highlighting, add range operators to operator list df11ee40f
  • invalid uri on windows for links in hover tooltip 179d55946
  • increase max buffer size for zscript process, which was breaking editor for large scripts 2169c67a3

ZLauncher

  • "Static for invalid data" option not working in zlauncher 3c7fd0a15
  • hide update tab on linux 39cb605e5
  • remove defunct "Allow Multiple Instances" option 5e78d1603

Web

  • use zc-data.nyc3.digitaloceanspaces.com for now 78e7c8441
  • "Copy URL" in player now uses correct test params 6899e872a
  • sync fs when writing save order txt file b38097bd6
  • quick save creation link working again d030fe7c5  

    The quest gamedata field was inadvertently set to 0 because the save file was prematurely selected before being saved for the first time, which prevented anything in saves_do_first_time_stuff from sticking.

  • improve sfx on title screen by yielding during quest load 424f6200c
  • handle reaching end of script in wasm jit eb3dc8a7a
  • handle CMP_BOOL in jit wasm 35fc59b6b
  • skip titlescreen for quick open links 840e2ef7b
  • disable broken parallel processing for zasm opt cc0518ae6
  • avoid performance hit by disabling info bitmap 2a6812a96
  • packaged quests not loading correctly 49b71a2a1

Documentation

  • add a couple missing subscreen widget script docs 9b84f3802
  • document DrawTile '-777' rotation behavior de7cccefe
  • fix typo d4ff09563
  • update zstrings.txt to mention the "Insert SCC" button fef251974
  • fix some issues with the webdocs 0fd60cc13
  • fix 'subscreendata->PosDirs[]' being misdocumented as '->Poses[]' dfe9d12a4

Editor

  • touch up attack/whimsical ring help text ('damage' -> 'power') c5da0a5c6

ZScript

Build

Web

Refactors

  • remove unused 'VSync' option (it didn't do anything) 505aff7ff
  • don't tint behind dropdown lists (allow skipping dlgs tint) 3da82ef18
  • enable allegro DEBUGMODE in debug builds 7edeafd15  

    This enables allegro asserts, among other things. zc_alleg.h attempted to enable for every build type, but it actually had no effect since allegro is built as as separate target.

  • Menus (new sleeker look, much cleaner backend) 03339654b
  • key files c6f1ea5f3  

    Now work from the folder the quest is in OR the exe is in, and saves to the folder the quest is in. Also cleaned up the code for handling reading key files.

  • share common allegro app setup 05eb72d5b
  • remove unsupported color_depth option c9fad269b
  • load text files more efficiently 0964f7481
  • remove scary and now pointless warnings when toggling fullscreen 75f9d356a
  • remove expensive busy loop in render throttler 6d36424bb  

    Replaces a busy loop with a much cheaper mutex condition variable to control FPS.

    The maxfps option now works for values less than 60 fps.

  • use enums instead of defines for many flag values 806180bea
  • combine misc attributes for guys into array (#955) 4e949df18  

    Co-authored-by: Emily 35015090+EmilyV99@users.noreply.github.com

  • reduce amount of copying in readmaps 79b34ae78  

    This makes loading yuurand.qst 21% faster (2445ms -> 1927ms)

Player

  • remove unused volume code in read_saves c4000cb70
  • move x64 backend jit code to separate file 9ff9a9a70
  • add null jit backend ec0a84ab4
  • move debug zasm writing to new -extract-zasm command 847ab88e9  

    This allows for all scripts in a qst to be written to disk, instead of only the ones that happen to execute.

  • move global inits from init_game to new init_game_vars 7f180a32d
  • make lamp_paid not static for replay determinism 90a876adf
  • use common structured zasm utilities in jit_x64.cpp c40c79a06
  • simplify how structured zasm finds functions 46bc924ed
  • split some zasm opts into separate script-level pass 3f4f964dc
  • assume modern function calls in zasm optimization passes e260ce752
  • remove ZASM debugger from menu 1da2d02a3  

    You may still activate this with [CONSOLE] print_ZASM = 1 in zc.cfg, but the option is no longer in the player menu. This will be removed entirely soon - it's so slow it can lock up a computer, and not useful enough to keep around.

    We may introduce a proper debugger in the future for ZScript to serve the purpose the ZASM debugger tried to.

  • move get_register_dependencies to zasm_table.cpp 13b6a599c
  • remove extra draws to scrollbuf in draw_screen 2f47c11fc
  • remove digi_music volume control 88c037791  

    digi_music is a global volume control for all allegro 4 music streams, which is only used for GME (so all those chiptune formats). But we already apply emusic_volume (enhanced music) to all non-MIDI music, so digi_music was at best redundant, and at worse a confusing knob that only modified some music formats.

    It's been removed from the Sound dialog, and now defaults to 255 (100%). It can still be modified via scripts, though this should be changed to just set/read emusic_volume sometime in the near future.

    BTW - ~6 months ago OGG was changed to use Allegro 5 instead of 4, which means at that point digi_music no longer had any effect on OGG volume.

  • remove music buffer setting 572f44514  

    This only applied to it/xm/s3m/mod music. There's no need to expose this to users. Instead, always use 128KB as a buffer size.

  • add get_command_implicit_dependencies in zasm_table.cpp 9e4a41e07
  • add get_register_ref_dependency in zasm_table.cpp ced4dbad8  

    Also run propagate_values after the comparison opt passes, as it was accidentally skipping some optimizations due to the comparisons passes assuming D2 is being compared.

  • simplify zasm simulation and always simulate stack 37d86217d
  • optimize zasm scripts in parallel 9ae7f4e86
  • improve handling of bugged SDDDD by fixing it, instead of deopting df037da33
  • reduce duplicated code for trigger conditionals

      Relevant changes:

    • refactor(zc): reduce duplicated code for trigger results f20ddc1b4
  • rename the "ZScript Debugger" to "ZC Console" d44b13ffa
  • add cache to generation of translucency tables c38897790  

    This took up a lot of CPU time during the titlescreen and during animations such as screen wipes / triforce pickup / etc.

  • clean up jinx handling (#939) cfe48cd7b
  • remove epilipsey dialog on fresh install, add toggle in launcher e888bff41
  • remove prompt about recording when starting a new save file dc77b2020
  • deduplicate enemy code reading of SIZEflags 92bb2cc6a
  • remove old movement functions c5b8a0e17

Editor

  • Clean up Tile/Side/Ring warp dialogs 2637fc6ac
  • re-organize the combo editor 'Triggers' tab 53310a254
  • add sub-menu for changing tile color depth a9cda26e6
  • redesign enemy editor using new GUI (#971) e33551759
  • upgrade enemy editor's enemy selector to new gui (#986) b7e767fd4

ZScript Standard Library (std.zh)

  • remove instances of deprecated functions 331bbd4e3
  • delete unused and unwanted stuff 48660bfcb  

    These files have been deleted from the std library:

    • std_zh/assert.zh
    • std_zh/astar.zh
    • std_zh/infostring.zh
    • std_zh/math.zh
    • std_zh/std_legacy.zh
    • std_zh/std_meta.zh
    • std_zh/std_update.zh
    • std_zh/std_user_defs.zh
    • std_zh/std_vars.zh
    • std_zh/weapon.zh

     

    These files either do not belong in a standard library (too specific), are not finished, or otherwise provide little to no value so are just a maintenance burden.

  • make every std file compile individually 6de1bb98b
  • move some constants from std to bindings, and add more doc comments 45d9718e1

ZScript

  • optimize script lookup by name d13fb8b04
  • manually parse config file, drop al_init 74bfb6f82
  • copy script entry to tempfile quicker 97b01d5d7
  • internal function aliases, internal constexpr functions 17e03bc81
  • use alias name in comments, update expected zscript b0af4b4b8
  • reserve 'constexpr' token 0cb3519ea
  • clean up ScriptEngineData for all script types 584bea132
  • clean up generic script indexing a27241f73
  • optimize bool ops a lot c8fae535d
  • clean up getStackOffset(Datum) code 3cdf73853
  • label opcode register args as R/W/RW/unused 40e805b55
  • label some opcode properties with flags c11ec7172
  • use common UserDataContainer for most user data ba6e421d9
  • standardize script object management be20f347b  

    This keeps script-created objects in the same map, gives all objects a unique id, and implements allocation and retrieval for any object type using the same methods. This reduces some duplicated code, and should help with implementation of a potential garbage collector feature.

    Bitmap objects are a bit special, and still need to be refactored.

  • document, clean up, and sanity check websocket stuff ce2f07d9c
  • document, clean up, and sanity check websocket stuff 764e539e0
  • migrate user_bitmap to script object system 68329daf9  

    Incidently, this increases the maximum number of user bitmaps to 256.

  • better 'read-only' compile warnings bffa9428d  

    also makes aliases of getters/setters work

  • move zasm table and serialization to shared lib c483f611c
  • remove separate zasm defines for compiler bcd079539
  • improve location of many error messages 52949459f
  • reduce the scripts included by default eed542419  

    This removes some scripts that aren't useful, or aren't a good fit for default inclusion.

    • delete gameover_menus.zh
    • delete LISP.zh
    • delete Music.zh
    • delete sprites.zh
    • delete styles.zh
    • delete theRandomHeader_v2.zh
    • delete ZVersion.zh
    • delete tango/1.0 and tango/1.2 (keeping just 1.3)
    • move sram.zh to deprecated/sram.zh
    • move theRandomHeader_v3.zh to deprecated/theRandomHeader.zh
    • move time.zh to deprecated/time.zh
    • move example scripts to headers/examples
    • remove std including EmilyMisc.zh - include yourself as needed
  • deprecate many getters/setters, replace with variables 46ca3bfa8  

    ~40 built-in methods exist in this style:

    int Max(); // Returns the max.
    void Max(int value); // Sets the max.
    int GetCurDMapScreen();

    These have been deprecated and replaced with a variable, like so:

    int Max; // The max number.
    int CurDMapScreen;
    
  • move internal symbols to new binding .zh files 011539980  

    Internal symbols were defined in .cpp files, but now they are defined in .zs files with a new internal keyword and @zasm doc comments. These files live in bindings, and are automatically included for every compilation.

    This should simplify the process of adding new internal symbols. It also enables viewing documentation of any internal symbol in the VS Code extension (w/ a hover tooltip), and all the documentation we have for internal functions and variables has been inserted as comments in the binding files.

    This also deprecates functions that create an object of internal types, like Game->CreateBitmap(width, height) - and replaces with normal constructors - new bitmap(width, height).

  • remove library symbol cpp files 76a67b371
  • remove internal class type b76078275
  • array literals better deduce their element types 3717da293
  • use faster register allocation in jit 50b8b0bf2  

    asmjit's register allocation was using a bin-packing algorithm. This turns out to be very slow for the assembly that our jit compiler emits, since the vast majority of variables exist for only a single basic block. Instead of bin-packing, the much faster and simpler linear scan register allocation algorithm is now used.

    For a very large 200k-instruction script, compilation went from 19.5s to 2.8s (a 85% decrease).

    With this improvement, the 20k-instruction limit for jit has been removed. One example of the impact of this is that yuurand.zplay, which the jit compiler was previously mostly disabled for since most of its scripts are huge, now has all its scripts compiled. This increased the average FPS for yuurand.zplay from ~320 to ~2000, while still reducing the total time spent compiling.

    Theoretically this change in register allocation may produce slower runtime code, but there was no drop in FPS realized in the maths.zs stress test.

  • remove ZASM debugger bb5404c8d  

    This was already made inaccessible from the GUI in 1da2d02, but now it is removed entirely. Work on a real debugger will begin soon.

  • type-safe opcode classes and use zasm table for stringification 75dc4d745
  • separate zasm code from script data 75f981f57
  • make all command strings match enum name 08e0c08e5  

    This normalizes all the string names for commands to be the same as the enum name used in code, and rewrites get_script_command to be an explicit mapping of this string representation and the enum value. These not matching was confusing, and was a potential source of future bugs.

  • tweak Region-> and screen script internals in preparation for z3 7b421826c  

    Region->OriginScreen is now of type screendata, and Region->OriginScreenIndex is added to return just the screen index.

    Similar change made to Region->GetScreenForComoboPos(int pos).

  • remove unused features from ZScriptArray c09b58133  

    Various things are just a wrapper around what std::vector does, and we don't need dimensions, a template, or a custom iterator.

  • remove duplicated function deallocateZScriptArray d061e3c55
  • remove unused greyscale and monochrome filters b4bd8ad99  

    Removes these methods:

    • Graphics->Greyscale()
    • Graphics->Monochrome()
    • Game->GreyscaleOff()
    • Game->GreyscaleOn()

     

    None of these are used in published quests, Graphics->Tint() and Graphics->MonochromeHue() can be used instead, and removing these simplifies some rendering logic.

  • remove option to configure run function name 31c10d7d9
  • add -json switch to parser, use stderr for logging 3be9b16e8
  • add errors and warnings to json output as diagnostics 6ae06e15d
  • improve validation of file paths 0480ad034  
    • .. is now allowed in paths, as long as it doesn't reach above the quest's "Files" folder
    • more specific error messages when path is invalid
    • check for illegal filenames
    • general clean up of path validation code

Visual Studio Code Extension

  • use new -json zscript option for diagnostics 1143e7480

Tests

  • save replay result file when starting replay cb2e4b0d3
  • suppress timeout check on frame 0 9f94de5ca
  • fix get_recent_release_tag method 3b24464b1
  • update 'triggers.zplay' d9baf5c89
  • add '--output' option for zscript tests 2574f1b9e
  • fix zscript subfolder tests not running (and update) 7ff5efcf2
  • update 'armos.zs' expected zasm 8ccc152f6
  • update errors_2_expected.txt c2c5cc3e5
  • filter out expired test builds in bisect_builds.py f5ca9056d
  • prevent infinite loop when zplayer exits before first frame 64e2ddf52
  • extract snapshot testing code to base class d9d839b21
  • add snapshot tests for x64 jit 07a6ef713
  • add nargads_trail_crystal_crusades.zplay 3f6d2943a
  • fail replay test if jit cannot compile a script 1bf248ab2
  • fix local webserver when offline e9d7846d4
  • include js script in web replay test stdout/stderr 2790c4fe8
  • fix --split-threshold cli arg for split_replay.py 886ab0507
  • add umbral_cloud.zplay 3f56dc889
  • fail on abort in web replay tests 2b643c358
  • stop on fatal errors in run_web_version.js bafc72eba
  • set write_to_disk in saves_test 334174ce5
  • fix test_jit.py not looking in the right folder anymore 44227cd6e
  • add "frames" and "length" meta fields to zplay 93e77ddf7
  • use "latest" version for all playground.qst replays 3c80d2439  

    These replays should be trivial to update as needed, and using no replay compat code makes them far more useful for verifying specific features.

  • add test_optimize_zasm.py and update_snapshots.py 6b8053c89
  • move snapshot files to common folder 47eb8e745
  • hash jit output for all but playground.qst 8a28eff6b
  • add scripts/run_for_every_qst.py, for running a command against every qst in the database 0eb93f48d
  • add replay test for class ctor/dtor 57c8cc5e1
  • fix different outputs for jit snapshots 179f96858
  • add link_to_the_heavens.zplay dc4100fc4
  • define calling convention for jit regression tests 03e3f0871
  • add playground_exstate.zplay and playground_large_animations.zplay d61aeb1bc
  • add dinus.zplay f7de776de
  • add grassland_attack.zplay b08c36d99
  • add crucible_quest.zplay 5dd7d4c23
  • add combo_rotator.zplay 543bcfb5f  

    This is the first of more planned script replay tests, which along with the playground.qst replays will be re-compiled with the latest zscript in CI and their replays re-verified. Should result in better test coverage for newer compiler features.

  • fix crucible_quest.zplay from recent slope refactor 3a3dba0d0
  • make the editor File->New test do what it says it does 3314b4ef0
  • add goriya_moblin_war.zplay c6c9c0403
  • add 100_rooms_of_wisdom.zplay 05c193337
  • add dragon_ball_z.zplay e3ac9dd62
  • add new_beginnings.zplay bb2304e08
  • add kriztles_3.zplay c45defff6
  • add final_fantasy.zplay d025e77ea
  • add zelda_3000.zplay b4a2b4c88
  • use original qst for combo rotator replay b093e59c6
  • update crucible_quest.zplay for 5732b53 798646bc4
  • add local web app for running replay tests bd16f16e0
  • move build archive operations to archive.py 144ec7f33  

    This greatly cleans up bisect_builds.py, which was doing a lot. Now a new tool scripts/archive.py is responsible for downloading any build - or building from source, as needed.

  • avoid enumerating s3 bucket just to download single version e1b37622b
  • use new archive download for run_replay_tests.py f2eaaf7ec  

    This removes the old download flow that required a github api key to get a baseline build for a compare report.

  • move github related functions to github_helpers.py deb47752d
  • use requirements.txt for python deps 61941b504
  • extract core replay runner to replays.py a2ab3ac30
  • format Python using Black c54f26195
  • sort Python imports using isort 2cabfdb7c
  • include palette in gfx frame hash 6f33284ea
  • fix hash for compare replay image dedupe 4f739c9d7  

    The previous hash did not take into account the image format's color palette, so hash collisions prevented some failing frames from showing.

  • update expected zasm from recent changes ed025a972
  • add the_deep.zplay 9268cc100
  • add enigma_of_basilischi_island_basilse.zplay ee3e6e7c3
  • refactor how known replay failures are handled 85f745323
  • import Path directly 2fd240321
  • remove solid.zplay 2b3acd742
  • add playground_bitmap_credits.zplay d6b398ad4
  • add tests for read-only vars and deprecation 29094bbe5
  • add eiyuu.zplay 982031f5c
  • make some test scripts emit no warnings 6720fc50e
  • update test scripts for new array syntax 873e7ecd6
  • add item_spawns_cloud.zplay 0ab66ae79
  • add crucible_quest_short_1.zplay f7650745d
  • add newbie_boss.zplay and recompile test b1b4d8203
  • add snapshot test for compiling the zscript database 46e71c1d8
  • use truecolor bitmap for gfx frame hash bd2cf5c9b

CI

  • for web tests, build for RelWithDebInfo 16ce632d5
  • include coverage for all apps, not just zplayer c0e0151c4
  • update vcpkg 4d2fe65d5  

    Apparently vcpkg has issues with retaining build assets long term. Being forced to update to latest as something we need expired.

    microsoft/vcpkg#30546 (comment)

  • bump build cache so 2.55 branch doesn't conflict 75da202d6
  • set correct test results folder for web replays for upload 2ebfaeffc
  • use improved lfs cache c9d81ef25
  • use RelWithDebInfo for win32 tests d621d710a
  • get database update cron working again 15b7ff4aa
  • upgrade actions due to node 16 deprecation fb3744bdd
  • fix type in download-artifact v4 action ec499225b
  • fix another typo in download-artifact v4 action e272d0914
  • upload releases to s3 bucket 99759bbdf
  • set test results folder names for jit/non-jit replay runs bfd9daa06
  • use macos-13 for newer clang

      Relevant changes:

    • ci: update to macos-13 in other places too 6bb570d37
  • fix replay report generation for forks bbb53680f

Misc.

  • Allow scrolling info popups 7405aa0c4
  • Remove '(Experimental)' label from FFC solidity c98b5f0a9
  • Remove whistle delay for new replays 9bf0e2a7b
  • minor replay/debug improvements 4fe60ce1f
  • add min replay size threshold when splitting replays 5cc021de4
  • add 'peekkey()' / 'upeekkey()' local allegro edits 933422607
  • clean up menus, particularly the zc main menu 43a43345c
  • add jit_runtime_debug.py for debugging jit bugs 781ffbc00
  • update default fonts to be same between base_config and 'Default:' button 070edf5c7
  • help text to indicate use of A1/A2 values on ffc/item editors cc3c71b19
  • remove noisy allocation logs 6319e54ac
  • Revert "fix!: more lens/enemy stuff missed in prior commit" fbc664523  

    This reverts commit b9cafe07b073b7de07bb2f27207582bc8d435d62.

  • Revert "fix: changer ffcs counting for trigger groups and similar effects (they shouldn't)" bf50df15b  

    This reverts commit 1a1bd37ac769db838a390e88b6fef03288576b01.

  • add qst.author sentry tag, so we can know who to reach out to for crashes in unpublished quests 48fbd2609
  • remove tilesets/classic.qst d943f79a2  

    The default quest (File->New) makes this not necessary.

  • fix(zq): upgrade combo 'move' code, more things now update on moving combos, add Combo overwrite warnings (#917) e8d903186
  • update themes cb05cf84d
  • Revert "ci!: use pull_request_target for ci.yml workflow" fab9eefc0  

    This reverts commit 40d18af060793860c7757fd69f8e5defd15e59c2.

  • Revert "refactor(zc): remove old movement functions" 87b073771  

    This reverts commit c5b8a0e17d165380f44ddf7950a73b6aa216d3ad.

Player

  • show current frame count when recording and system menu is active 346eec032
  • improve error message when qst title does not match save file 33b36ed95
  • support "latest" for version field in zplay dcaf7f925
  • add -analyze-zasm-duplication for finding duplicated functions aa467263c  

    Not fully finished, just a start.

  • temporarily disable compare zasm opt as I improve in a branch 52d0aa35a
  • disable zasm optimization until reported issues with tango are fixed c3b7e1ba2
  • add qst_title, qst_hash as replay meta fields 2e0ed2b04

Editor

  • upgrade combo 'advanced paste' dialog, add 'Adv. Paste' to rclick menu d69805ccd
  • Add hotkey for rebinding hotkeys 298b54e9d
  • fix some text, add divine escape help text for warp types ea92590b9
  • clean up 'Door Combo Set' dialog/hotkeys and document them a1a169eb5
  • disable auto save for new, unsaved quest 07fd3c524

ZScript Standard Library (std.zh)

  • update headers and bindings with array typing b23b23484

ZScript

  • optimize '!' operator cb8cbe038
  • more parser optimizations 900178b73
  • Optimize multiple consecutive PUSH opcodes dc6d9e49e
  • Add ZASM comments to parser output 407bcf258
  • add more ZASM comments 4b1dd0988
  • CALLFUNC/RETURNFUNC for optimized function call/return 5aa14b335
  • New 'ReturnVisitor' pass errors on functions missing 'return' statements 5cc8fb151
  • code reachability optimizations 17ae5ad31
  • more small ZASM optimizations 76f86d2a7
  • add compile option for missing return error 18275ed76
  • treat empty functions like prototype functions 433581fe7  

    This can be a heavy optimization for empty constructors/destructors.

  • make some more internal functions constexpr 21cdf3c04
  • re-number zasm comment numberings 3ea93b743
  • Optimize 'STORED' followed by 'LOADD', and add 'STOREDV' 6fce11564
  • Optimize standing-statement x++,x-- to ++x,--x 5b62f2f5c
  • optimize sections of zasm that are run only for their side-efffects d253cbb84
  • Optimizations related to function call parameters, unused function params d79b131ab
  • range loop cleanup 9841db7d5
  • Optimize variables initialized to 0 f20abd31d
  • clean up unused variables f3a0991d6
  • internal label errors now prevent compile beb767112
  • add 'itemdata->LAttributes[]' to access attributes as a full 32-bit long value 136e7fa2a
  • compare related optimizations 3a0d346dc
  • allow 3-arg opcodes, move zasm tables to remove duplication 0c3e0823b
  • optimize comparisons to run when used, add CMP_BOOL flag for boolean-equality comparisons aa9bf8ebb
  • support CMP_BOOL in x64 jit accf84bf0
  • add Region in anticipation of z3 scrolling f87c20d08  

    To enable scripts to work in 2.55 and in a future release with z3 scrolling, we are adding a non-functional Region:

    • Region->Width: width in pixels (today, always 256)
    • Region->Height: height in pixels (176)
    • Region->ScreenWidth: width in screens (1)
    • Region->ScreenHeight: height in screens (1)
    • Region->NumCombos: number of combo positions (176)
    • Region->ID: region id (0 - meaning just a normal 1x1 area)
    • Region->OriginScreen: top-left screen in the region
    • Region->GetScreenForComboPos(int pos): given a combo position, returns the screen index associated with it
    • Region->TriggerSecrets(int screen_index): trigger secrets for given screen. The screen must be in the region

     

    For example, if a script uses Region->NumCombos instead of 176 to iterate all the combos in the current area, it will work in both regions and non-regions. Additionally you should use ComboAt(x, y) rather than anything else to translate between pixel coordinates and a combo position.

  • mark combo->CSet deprecated, in favor for the better named ->CSet2 691450338
  • optimize PEEK in x64 and wasm jit 0ff7dee9e
  • use faster LOAD/STORE instead of LOADD/STORED in compiler e8b3be6fd

Visual Studio Code Extension

ZLauncher

  • remove tounge-in-cheek tooltip from Fullscreen checkbox 40167c734
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment