* Added Feature Flag support, run doodle with --experimental to enable
all flags. Eraser Tool is behind a feature flag now.
* + and - on the top row of keyboard keys will zoom the drawing in and
out in Edit Mode. The wallpaper zooms nicely enough, but level
chunkers need work.
* A View menu is added with Zoom in/out, reset zoom, and scroll to
origin options. The whole menu is behind the Zoom feature flag.
* Update README with lots of details for fun debug mode options to play
around with.
* pkg/keybinds holds central functions to check global keybinds, like
DebugOverlay (F3), Undo (Ctrl-Z), GotoPlay/GotoEdit (p/e), etc.
* The Tools menu in the editor mode lists out more options to select
various drawing tools (line, pencil, etc.) - and showing the hotkey
for each tool.
* When editing a doodad in the Editor Mode, the toolbar has a "Lyr."
button that opens the Layers window.
* The Layers window allows switching the active doodad layer that you
are drawing on, as well as create and rename layers.
* With this feature, Doodads may be fully drawn in-game, including
adding alternate named layers for animations and multiple-state
doodads.
* Update the Pager component to have a configurable MaxPageButtons.
Controls that have more pages than this limit will stop having buttons
drawn after the limit. The "Forward" and "Next" buttons can still
navigate into the extra pages.
* Refactored and centralized the various popup windows in Editor Mode
into editor_ui_popups.go; the SetupPopups() and various methods such
as ShowPaletteWindow() and ShowDoodadDropper() make management of
popups simple for the editor_ui!
* The Menu Bar in Editor Mode now has context-specific tools in the
Tools menu: the Doodad Dropper for levels and Layers for doodads.
* Bugfix the Palette Editor window to work equally between Levels and
Doodads, by only having it care about the Palette and not the Level
that owns it.
* Adds global modal support in the pkg/modal/ package. It has easy
Alert() and Confirm() methods to prompt the user before calling a
callback function on affirmative response.
* Modals have global app state: they're processed in the main loop in
pkg/doodle.go similar to the global command shell.
* When a modal is active, a semitransparent black frame covers the
screen (gameplay loop paused, last game frame rendered below) and the
modal window appears on top.
* The developer console retains higher priority than the modal system
and always renders on top.
* Editor Mode: track when the level pixels have been modified, and
confirm the user about unsaved changes when they attempt to close the
level (New, Open, Close, etc.)
* Global: the Escape key no longer immediately shuts down the game, but
will confirm the user's intent via a modal.
* File->Quit in the Editor Mode also invokes the confirm shutdown modal.
* Start the program window maximized with the `-w maximized` CLI option.
* Move the Doodad Palette off the right-side dock of the Editor Scene and
into its own pop-up window: the DoodadDropper.
* Shrink the width of the Color Palette panel and show only the colors in
the buttons. The name of the swatch is available in the mouse-over tooltip.
* Added an "Edit" button to the Color Palette. It opens a Palette Editor
window where you can rename, change colors and attributes of existing colors
OR insert new colors into your palette. (Deleting colors not yet supported).
* level.Chunker gets a Redraw method: invalidates all cached textures of all
chunks forcing the level to redraw itself, possibly with an updated palette.
* Integrate the new ui.MenuBar into the Editor Scene.
* File: New Level/Doodad, Save [as], Open, Close, Exit
* Edit: Undo, Redo, Level options
* Level: Playtest
* Tools: Debug overlay, Command shell
* Help: User Manual, About
* Add an About dialog accessible from the Help menu.
* Two-state Buttons now also subscribe to the state change message, so
other on/off buttons in the same level update to match the state of
the button that was hit.
* Add lock mutexes around the scripting engine to protect from
concurrent event handlers.
* New logger module supports js/wasm build by skipping the dependency on
ssh/terminal (which detected interactive consoles, not applicable to
JS). In WASM the logs go to the browser console and ANSI color codes
not needed.
* Discovered a bug where if you hit the Undo key to erase pixels and an
entire chunk became empty by it, the chunk would have rendering errors
and show as a solid black square instead of the level wallpaper
showing through.
* Chunks that have no pixels in them are culled from the chunker
immediately when you call a Delete() operation.
* The level file saver also calls a maintenance function to prune all
empty chunks upon saving the file. So existing levels with broken
chunks need only be re-saved to fix them.
* Implement Brush Sizes for drawtool.Stroke and add a UI to the tools panel
to control the brush size.
* Brush sizes: 1, 2, 4, 8, 16, 24, 32, 48, 64
* Add the Eraser Tool to editor mode. It uses a default brush size of 16
and a max size of 32 due to some performance issues.
* The Undo/Redo system now remembers the original color of pixels when
you change them, so that Undo will set them back how they were instead
of deleting the pixel entirely. Due to performance issues, this only
happens when your Brush Size is 0 (drawing single-pixel shapes).
* UI: Add an IntVariable option to ui.Label to bind showing the value of
an int reference.
Aforementioned performance issues:
* When we try to remember whole rects of pixels for drawing thick
shapes, it requires a ton of scanning for each step of the shape. Even
de-duplicating pixel checks, tons of extra reads are constantly
checked.
* The Eraser is the only tool that absolutely needs to be able to
remember wiped pixels AND have large brush sizes. The performance
sucks and lags a bit if you erase a lot all at once, but it's a
trade-off for now.
* So pixels aren't remembered when drawing lines in your level with
thick brushes, so the Undo action will simply delete your pixels and not
reset them. Only the Eraser can bring back pixels.
* The game's tick counter was moved from Doodle.ticks to shmem.Tick
where it is more easily available from every corner of the code.
* Fix a bug in the Level Editor where dragging an already-existing actor
from one part of your map to another, would cause it to lose all its
data (especially its UUID), breaking links to other doodads. Now the
existing Actor catches a ride on the drag object to be reinserted
later.
* Animate the Link Line visualizers between actors. They now animate a
blinking color between magenta and grey-ish.
* Add a Level Exit doodad, which for now is a little blue flag on a pole
that reads "END"
* JavaScript API: global function EndLevel() will end the level. The
exit doodad calls this when touched by the player.
* Add a "Level Completed" alert box UI to PlayScene with dynamic button
layouts.
* The alert box pops up when a doodad calls EndLevel() and contains
action buttons what to do next.
* "Play Again" restarts the current level again.
* "Edit Level" if you came from the EditorScene; otherwise this button
is not visible.
* "Next Level" is a to-be-implemented button to advance in the single
player story mode. Only shows up when PlayScene.HasNext=true.
* "Exit to Menu" is always visible and closes out to the MainScene.
* Refactor texture caching in render.Engine:
* New interface method: NewTexture(filename string, image.Image)
* WASM immediately encodes the image to PNG and generates a JavaScript
`Image()` object to load it with a data URI and keep it in memory.
* SDL2 saves the bitmap to disk as it did before.
* WASM: deprecate the sessionStorage for holding image data. Session
storage methods panic if called. The image data is directly kept in
Go memory as a js.Value holding an Image().
* Shared Memory workaround: the level.Chunk.ToBitmap() function is where
chunk textures get cached, but it had no access to the render.Engine
used in the game. The `pkg/shmem` package holds global pointers to
common structures like the CurrentRenderEngine as a work-around.
* Also shmem.Flash() so Doodle can make its d.Flash() function
globally available, any sub-package can now flash text to the screen
regardless of source code location.
* JavaScript API for Doodads now has a global Flash() function
available.
* WASM: Handle window resize so Doodle can recompute its dimensions
instead of scaling/shrinking the view.
* Add RGBA color blending support in WASM build.
* Initial texture caching API for Canvas renderer engine. The WASM build
writes the chunk caches as a "data:image/png" base64 URL on the
browser's sessionStorage, for access to copy into the Canvas.
* Separated the ClickEvent from the MouseEvent (motion) in the WASM
event queue system, to allow clicking and dragging.
* Added the EscapeKey handler, which will abruptly terminate the WASM
application, same as it kills the window in the desktop build.
* Optimization fix: I discovered that if the user clicks and holds over
a single pixel when drawing a level, repeated Set() operations were
firing meaning multiple cache invalidations. Not noticeable on PC but
on WebAssembly it crippled the browser. Now if the cursor isn't moving
it doesn't do anything.
* Refactor the event system in the WASM render engine to serialize the
async JavaScript events into a channel, so that queued events are read
off serially in the main loop similar to SDL. This fixes keyboard
input issues, altho if you type really fast some input keys get lost.
* Initial WebAssembly build target for Doodle in the wasm/ folder.
* Add a new render.Engine implementation, lib/render/canvas that uses
the HTML 5 Canvas API instead of SDL2 for the WebAssembly target.
* Ported the basic DrawLine(), DrawBox() etc. functions from SDL2 to
Canvas context2d API.
* Fonts are handled with CSS embedded fonts named after the font
filename and defined in wasm/index.html
* `make wasm` builds the WASM program, and `make wasm-serve` runs a dev
Go server that hosts the WASM file for development. The server also
watches the dev tree for *.go files and rebuilds the WASM binary
automatically on change.
* This build "basically" runs the game. UI and fonts all work and mouse
movements and clicks are detected. No wallpaper support yet or texture
caching (which will crash the game as soon as you click and draw a
pixel in your map!)
* Debug mode: no longer enables the DebugOverlay (F3) by default, but
does now insert the current FPS counter into the window title bar.
* ui.Frame: set a default "mostly transparent" BG color so the frame
background doesn't render as white.
* Add the MenuScene which will house the game's main menus.
* The "New Level" menu is first to be added.
* UI lets you pick Page Type and Wallpaper using radio buttons.
* Page Type: Unbounded, Bounded (default), No Negative Space, Bordered
* Fix bugs in uix.Canvas to fully support all these page types.
* Add a Red Azulian as a test for mobile enemies.
* Its A.I. has it walk back and forth, changing directions when it
comes up against an obstacle for a few moments.
* It plays walking animations and can trigger collision events with
other Doodads, such as the Electric Door and Trapdoor.
* Move Gravity responsibility to the doodad scripts themselves.
* Call `Self.SetGravity(true)` to opt the Doodad in to gravity.
* The canvas.Loop() adds gravity to any doodad that has it enabled.
* Build the app with -tags="shareware" to compile the free/shareware
build of the game.
* `make build-free` compiles both binaries to the bin/ folder in
shareware mode.
* The constant balance.FreeVersion is true in the shareware build and
all functionality related to the Doodad Editor UI mode is disabled
in this build mode.
* Add the JavaScript system for Doodads to run their scripts in levels,
and wire initial OnCollide() handler support.
* CLI: Add a `doodad install-script` command to the doodad tool.
* Usage: `doodad install-script <index.js> <filename.doodad>`
* Add dev-assets folder for storing source files for the official
default doodads, sprites, levels, etc. and for now add a JavaScript
for the first test doodad.
* Scenes can insert custom key/value labels to the debug overlay and
track string variables in real time
* Added ability to unthrottle FPS in main loop