* Install the new ui.TabFrame widget into the Settings and Doodad
Dropper windows to give them properly tabbed interfaces.
* Doodad Dropper's new tabs divide the list of doodads into categories
to make them easier to find.
* The officially defined categories so far are:
- Objects (Start/End Flags and Box)
- Doors (All locked doors and keys, Warp Doors, and Electric Door)
- Gizmos (All buttons, switches, state blocks/doors, Electric Door)
- Creatures (Blue/Red Azulian, Bird, Boy)
* The "All" tab of the Doodad Dropper will show every doodad regardless
of its category or whether it fit one of the official categories.
* How doodads are assigned categories is by a special "category" tag in
their metadata, e.g. "category=doors,gizmos" - multiple supported.
* The loading screen for Edit and Play modes is stable and the risk of
game crash is removed. The root cause was the setupAsync() functions
running on a background goroutine, and running SDL2 draw functions
while NOT on the main thread, which causes problems.
* The fix is all SDL2 Texture draws become lazy loaded: when the main
thread is presenting, any Wallpaper or ui.Image that has no texture
yet gets one created at that time from the cached image.Image.
* All internal game logic then uses image.Image types, to cache bitmaps
of Level Chunks, Wallpaper images, Sprite icons, etc. and the game is
free to prepare these asynchronously; only the main thread ever
Presents and the SDL2 textures initialize on first appearance.
* Several functions had arguments cleaned up: Canvas.LoadLevel() does
not need the render.Engine as (e.g. wallpaper) textures don't render
at that stage.
The Box can be pushed around by the player or other mobile doodads.
It is affected by gravity and can be pushed off ledges.
If the player gets under a box they can bump it up with their head.
* pkg/loadscreen implements a global Loading Screen for loading heavy
levels for playing or editing.
* All chunks in a level are pre-rendered to bitmap before gameplay
begins, which reduces stutter as chunks were being lazily rendered on
first appearance before.
* The loading screen can be played with in the developer console:
$ loadscreen.Show()
$ loadscreen.Hide()
Along with ShowWithProgress(), SetProgress(float64) and IsActive()
* Chunker: separate the concerns between Bitmaps an (SDL2) Textures.
* Chunker.Prerender() converts a chunk to a bitmap (a Go image.Image)
and caches it, only re-rendering if marked as dirty.
* Chunker.Texture() will use the pre-cached bitmap if available to
immediately produce the SDL2 texture.
Other miscellaneous changes:
* Added to the Colored Pencil palette: Sandstone
* Added "perlin noise" brush pattern
Note: this commit introduces instability and crashes:
* New `asyncSetup()` functions run on a goroutine, but SDL2 texture
calls must run on the main thread.
* Chunker avoids this by caching bitmaps, not textures.
* Wallpaper though is unstable, sometimes works, sometimes has graphical
glitches, sometimes crashes the game.
* Wallpaper.Load() and the *Texture() functions are where it crashes.
* Levels and Doodad files will be written in gzip-compressed JSON format
* `boolProp compress-drawings false` to disable compression and save as
classic JSON format directly
* The game can still read uncompressed JSON files
The file size savings on some built-in assets:
* Tutorial 2.level: 2.2M -> 414K (82% smaller)
* warp-door-orange.doodad: 105K -> 17K (84% smaller)
* Migrate off go-bindata to embed built-in fonts, levels and doodads in
favor of Go 1.16 native embed functionality.
* `make bindata` prints a deprecation warning to not break older build
scripts
* Removes all references of bindata from the program
* Holding Shift while pressing arrow keys in the editor will scroll by
just 1 pixel per tick to aid in precise debugging with the Zoom In/Out
feature.
* The keybinds used in canvas_editable.go to catch the arrow keys are
updated to use our nice keybind package. As a consequence, the WASD
keys will also scroll the level.
* The "d for Doodads" keybind is renamed "q" so as not to open the
Doodads window whenever scrolling right using the WASD keys.
WorldIndexAt() translates the pixel below the mouse cursor in screen
space (0,0 at top-left corner of the application window) into a world
coordinate in the level shown inside the canvas, taking into account the
canvas's position on the window and the scroll position.
It now translates correctly when zoom In or Out, so the "Abs:" mouse
position level in the status bar shows correctly.
Zoom features that are still jank:
- Scrolling while zoomed in, the chunks to the top/left start unloading
too rapidly and outpacing the scroll, eventually level is invisible
- Drawing and committing pixels to the image while zoomed in/out is
unpredictable where the pixels actually land.
- Actors in the level don't move or zoom at all.
* Got the level chunks AND the wallpaper to both scale UP and DOWN
consistently together.
* Trying to draw new pixels while zoomed in/out ends up offsetting the
pixels by 2X still. Still seems an issue between screen coordinates
and world coordinates. Zoom in 2X and try and draw a line 64px from
the corners of the screen? The committed line appropriately lands at
the 64px coord on the level data but, zoomed in, it appears 2X to the
right on the screen from where I dropped the cursor!
* When zooming OUT, the limit on number of chunks the viewport will try
and render is not increased, leaving dead space in the screen; more
chunks should render when there's room.
* The Windows build of v0.6.0 couldn't load embedded wallpapers such as
legal.png when asked, but could load the hard-coded default.png
* Root cause was the filesystem.FindFile() checking for path separators
in the filepath, and on Win32 this is \ but the internal wallpaper
paths use /
* Instead of a simple "cur. ver != latest ver" check, parse the Major,
Minor and Patch components and do a detailed check.
* So a x.x.1 release could be made for a specific platform that had a
bad build, and it won't mind when it sees the latest version is the
older x.x.0 build that other platforms had working fine.
* The pattern textures for level palettes have been brightened and work
better with bright colors.
* The three default palettes for new levels now have patterns applied to
each of their colors.
* Bugfix around resetting keybind states for Zoom In/Out, Scroll to
Origin and Reset Zoom Level bindings.
* Added a Settings window for game options, such as enabling the
horizontal toolbars in Edit Mode. The Settings window also has a
Controls tab showing the gameplay buttons and keyboard shortcuts.
* The Settings window is available as a button on the home screen OR
from the Edit->Settings menu in the EditScene.
* Bugfix: using WASD to move the player character now works better and
is considered by the game to be identical to the arrow key inputs. Boy
now updates his animation based on these keys, and they register as
boolean on/off keys instead of affected by key-repeat.
* Refactor the boolProps: they are all part of usercfg now, and if you
run e.g. "boolProp show-all-doodads true" and then cause the user
settings to save to disk, that boolProp will be permanently enabled
until turned off again.
* Free (shareware) versions of the game will not be able to Publish
Levels (attach custom doodads to the level file) and they will not be
able to load a level which relies on embedded doodads.
* The UI for the Publish Level window is still available, but clicking
on the confirm button will just open the Register (License) window.
* When loading a level containing embedded doodads: if some can't load
because they're embedded and you're using the free version of the
game, the error message is customized to reflect that.
* New command-line tool: doodle-admin for signing license keys for
users. Includes functions to initialize a keypair, sign license keys
and validate existing keys.
* The Main Menu screen shows a blue "Register Game" button in the bottom
right corner of the screen, for unregistered users only.
* In Edit Mode, there is a "Help -> Register" menu item that opens the
License Window.
* The License UI Window lets the user select the license.key file to
register the game with. If registered, a copy of the key is placed in
Doodle's profile directory and the licensee name/email is shown in the
License UI window.
* Unregistered games will show the word "(shareware)" next to the title
screen version number and Edit Mode status bar.
* No restrictions are yet placed on free versions of the game.
On small screen sizes like the Pinephone, the toolbars in the Level
Editor are best made horizontal across the top and bottom of the screen
leaving more room for the drawing.
Enable it with a boolProp for now, and then reopen the level editor:
boolProp horizontalToolbars true
When launching `doodle -w mobile` it will automatically enable this
option.
* The scrollbox by which the game follows the player character has been
revised, it is now an offset away from the window's center instead of
fixed pixel distances from the window's edges.
* Mobile form-factor (Pinephone) now scrolls OK instead of jerking back
and forth rapidly when moving left.
In the Level Editor, the "Level->Attached files" menu opens the
FileSystem Window, which shows a paginated list of attached files and a
"Delete" button to remove them.
- Custom doodads which also exist locally can be deleted from the
level's filesystem at any time.
- If a custom doodad does NOT exist locally, and one of them is still
placed somewhere within the level, you can not delete it.
- You can't delete the custom wallpaper image IF the level is still
using it. Change to a default wallpaper and then you can delete the
custom wallpaper image.
* The Publisher is all hooked up. No native Save File dialogs yet, so
uses the dev shell Prompt() to ask for output filename.
* Custom-only or builtin doodads too can be stored in the level's file
data, at "assets/doodads/*.doodad"
* When loading the embedded level in the Editor: it gets its custom
doodads out of its file, and you can drag and drop them elsehwere,
link them, Play Mode can use them, etc. but they won't appear in the
Doodad Dropper if they are not installed in your local doodads
directory.
* Fleshed out serialization API for the Doodad files:
- LoadFromEmbeddable() looks to load a doodad from embeddable file
data in addition to the usual places.
- Serialize() returns the doodad in bytes, for easy access to embed
into level data.
- Deserialize() to parse and return from bytes.
* When loading a level that references doodads not found in its embedded
data or the filesystem: an Alert modal appears listing the missing
doodads. The rest of the level loads fine, but the actors referenced
by these doodads don't load.
* File->Publish Level in the Level Editor opens the Publish window,
where you can embed custom doodads into your level and export a
portable .level file you can share with others.
* Currently does not actually export a level file yet.
* The dialog lists all unique doodad names in use in your level, and
designates which are built-ins and which are custom (paginated).
* A checkbox would let the user embed built-in doodads into their level,
as well, locking it in to those versions and not using updated
versions from future game releases.
UI Improvements:
* Added styling for a "Primary" UI button, rendered in deep blue.
* Pop-up modals (Alert, Confirm) color their Ok button as Primary.
* The Enter key pressed during an Alert or Confirm modal will invoke its
default button and close the modal, corresponding to its Primary
button.
* The developer console is now opened with the tilde/grave key ` instead
of the Enter key, so that the Enter key is free to click through
modals.
* In the "Open/Edit Drawing" window, a "Browse..." button is added to
the level and doodad sections, spawning a native File Open dialog to
pick a .level or .doodad outside the config root.
Palette swatches gain a new property: Pattern.
Patterns are grayscale textures that the swatch color will sample
against when drawing pixels to the level, by taking the world coordinate
modulo a value inside the texture.
A few algorithms were tried (Screen, Overlay), this branch lands on one
that tries to cast the color from grayscale which comes out rather dark;
to get a patterned color to look black while still seeing the pattern,
the color needs to be as bright as #777 to get the effect.
Adds a lazy scroll algorithm that basically:
- Zigzags right/down a certain distance, then up again
- Then enters a bounce phase where it bounces off the level
boundaries like a screensaver.
Arrow keys can still scroll the level manually, but the
automated scroll takes over otherwise.
* You can now browse for a custom wallpaper image to use with your
levels. A platform-native file picker dialog is used (no WASM support)
* In the New/Edit Level Properties dialog, the Wallpaper drop-down
includes an option to browse for a custom map.
* When editing an existing level: the wallpaper takes effect immediately
in your level once the file is picked. For NEW levels, the wallpaper
will appear once the "Continue" button is pressed.
* All common image types supported: png, jpeg, gif.
* The wallpaper is embedded in the level using the filepath
"assets/wallpapers/custom.b64img" as a Base64-encoded blob of the
image data.
* The `doodad show` command will list the names and sizes of files
embedded in levels. `doodad show --attachment <name>` will get an
attachment and print it to the console window.
* To extract a wallpaper image from a level:
`doodad show -a assets/wallpapers/custom.b64img | base64 -d > out.png`
* Replace the radio buttons for Page Type and Wallpaper with the new
SelectBox widgets from the UI toolkit.
* Choice of default palette also switched from a MenuButton to
a SelectBox widget.
* Experimental "Browse..." option added to the Wallpaper drop-down when
run in --experimental mode; not yet functional.
* In the "New Level" dialog, a "Palette:" option shows a MenuButton
drop-down with options: Default, Colored Pencil, and Blueprint. These
control the set of colors the new level starts with.
* Actors can now walk up gentle inclines to the left as well as they can
to the right. The bug was introduced as a hack to prevent clipping
thru the left wall of a 90 degree corner, but that problem seems
resolved now.
* The F4 key to draw collision boxes works reliably again: it draws the
player's hitbox in world-space using the canvas.DrawStrokes()
function, rather than in screen-space so it follows the player
reliably.
* The F4 key also draws hitboxes for ALL other actors in the level:
buttons, enemies, doors, etc.
* The level geometry collision function is updated to respect a doodad's
declared Hitbox from their script, which may result in a smaller box
than their raw Canvas size. The result is tighter collision between
doodads, and Boy's sprite is rather narrow for its square Canvas so
collision on rightward geometry is tighter for the player character.
* Collision checks between actors also respect the actor's declared
hitboxes now, allowing for Boy to get even closer to a locked door
before being blocked.
New doodad interactions:
* Sticky Buttons will emit a "sticky:down" event to linked doodads, with
a boolean value showing the Sticky Button's state.
* Normal Buttons will listen for "sticky:down" -- when a linked Sticky
Button is pressed, the normal Button presses in as well, and stays
pressed while the sticky:down signal is true.
* When the Sticky Button is released (e.g. because it received power
from another doodad), any linked buttons which were sticky:down
release as well.
* Switch doodads emit a new "switch:toggle" event JUST BEFORE sending
the "power" event. Sensitive Doodads can listen for switches in
particular this way.
* The Electric Door listens for switch:toggle; if a Switch is activated,
the Electric Door always flips its current state (open to close, or
vice versa) and ignores the immediately following power event. This
allows doors to toggle on/off regardless of sync with a Switch.
Other changes:
* When the player character dies by fire, instead of the message saying
"Watch out for fire!" it will use the name of the fire swatch that
hurt the player. This way levels could make it say "Watch out for
spikes!" or "lava" or whatever they want. The "Fire" attribute now
just means "instantly kills the player."
* Level Editor: You can now edit the Title and Author name of your level
in the Page Settings window.
* Bugfix: only the player character ends the game by dying in fire.
Other mobile doodads just turn dark but don't end the game.
* Increase the size of Trapdoor doodad sprites by 150% as they were a
bit small for the player character.
* Rename the game from "Project: Doodle" to "Sketchy Maze"
* The crumbly floor doodad was made 50% larger.
* New doodad: Small Key and Small Key Door. These work like the colored
doors and locks except each Small Key is consumed when it unlocks a
door. The door's appearance is of iron bars.
* The inventory HUD displays a small quantity label in the lower-right
corner of items that have a quantity, such as the Small Key. This is
done as a Canvas.CornerLabel string attribute on uix.Canvas.
* The "give all keys" cheat adds 99 Small Keys to your inventory.
* The "Use Key" (Q or Spacebar) now activates the Warp Door instead of a
collision event doing so.
* Warp Doors are now functional: the player opens a door, disappears,
the door closes; player is teleported to the linked door which opens,
appears the player and closes.
* If the player exits thru a Blue or Orange door which is disabled
(dotted outline), the door still opens and drops the player off but
returns to a Disabled state, acting as a one-way door.
* Clean up several debug log lines from Doodle and doodad scripts.