* Adds pkg/savegame to store user progress thru Level Packs.
* The savegame.json is mildly tamper resistant by including a checksum
along with the JSON body.
* The checksum combines the JSON string + an app secret (in savegame.go)
+ user specific entropy (stored in their settings.json). If the user
modifies their save file and the checksum becomes invalid the game
will not load the save file, acting like it didn't exist, resetting
all their high scores.
Updates to the Story Mode window:
* On the LevelPacks list: shows e.g. "[completed 0 of 3 levels]" showing
a user's progress thru the level pack.
* Below the levels on the Detail screen:
* Shows an indicator whether the level is completed or not.
* Shows high scores (fastest times beating the level)
* Shows a padlock icon if levels are locked and the player hasn't
reached them yet. Pops up an Alert modal if a locked level is
clicked on.
Scoring is based around your fastest time elapsed to finish the level.
* Perfect Time (gold coin): player has not died during the level.
* Best Time (silver coin): player has continued from a checkpoint.
In-game an elapsed timer is shown in the top left corner along with the
gold or silver coin indicating if your run has been Perfect.
If the user enters any Cheat Codes during gameplay they are not eligible
to win a high score, but the level will still be marked as completed.
The icon next to the in-game timer disappears when a cheat code has been
entered.
* The "Story Mode" button on the MainScene opens the levelpacks window.
* Levelpacks from all places are shown (built-in and user files), basic
level picker works.
* When playing a level out of a levelpack: the PlayScene gets the file
data from the zipfile and plays it OK.
* When a levelpack level is solved, the "Next Level" button appears on
the success modal and hitting Return will advance to the next level in
the pack. The final level doesn't show this button.
* The user can edit levelpack levels! Clicking the "Edit" button on the
Play Mode moves the loaded level over to the EditScene and the user
could save it to disk or edit/playtest it perfectly OK! The link to
the levelpack is lost upon opening in the editor, so the "Next Level"
victory button doesn't appear.
The title screen is now responsive to landscape mode. If the window is
not tall enough to show all the menu buttons (~600px) it will switch to
a horizontal layout with the title on the left and buttons on the right.
WIP "Story Mode" button that brings up a Level Packs selection window.
In the Level Editor, the "Level->Giant Screenshot" menu will take a full
scale PNG screenshot of the entire level, with its wallpaper and
doodads, and save it in ~/.config/doodle/screenshots.
It is currently CPU intensive and slow. With future work it should be
made asynchronous. The function is abstracted away nicely so that the
doodad CLI tool may support this as well.
* Tightens up the surface area of API methods available to the
JavaScript VMs for doodads. Variables and functions are carefully
passed in one-by-one so the doodad script can only access intended
functions and not snoop on undocumented APIs.
* Wrote tons of user documentation for Doodad Scripts: documented the
full surface area of the exposed JavaScript API now that the surface
area is known and limited.
* Early WIP code for the Campaign JSON
* In WASM build, user levels and doodads are written to localStorage
using their userdir path as keys (".config/levels/test.level")
* LoadFile() and WriteFile() for both Levels and Doodads interact with
the localStorage for WASM build instead of filesystem for desktop.
* userdir.ListLevels() and ListDoodads() for WASM scan the localStorage
keys for file names.
* userdir.ResolvePath() now works for WASM (previously was dummied out),
checks for the file in localStorage.
* Use `go-bindata` to embed built-in doodads and levels directly into
the Doodle binary. `make bindata` produces the bindata source file.
* Add `FromJSON()` method to Levels and Doodads to load objects from
JSON strings in memory (for bindata built-ins or WASM ajax requests)
* Update file loading functions to check the embedded bindata files.
* pkg/config.go#EditFile:
* Supports editing a level from bindata (TODO: remove this support)
* If the "assets/levels/%(simple-name.level)" exists in bindata,
edits that drawing.
* No such support for editing built-in doodads.
* WASM has no filesystem access to edit files except built-in
levels (yet)
* pkg/doodads#ListDoodads:
* Prepends built-in doodads from bindata to the returned list.
* WASM: no filesystem access so gets only the built-ins.
* pkg/doodads#LoadFile:
* Checks built-in bindata store first for doodad files.
* WASM: tries an HTTP request if not found in bindata but can go no
further if not found (no filesystem access)
* pkg/filesystem#FindFile:
* This function finds a level/doodad by checking all the places.
* If the level or doodad exists in bindata built-in, always returns
its system path like "assets/doodads/test.doodad"
* WASM: always returns the built-in candidate path even if not found
in bindata so that ajax GET can be attempted.
* pkg/level#ListSystemLevels:
* New function that lists the system level files, similar to the
equivalent doodads function.
* Prepends the bindata built-in level files.
* WASM: only returns the built-ins (no filesystem support)
* Desktop: also lists and returns the assets/levels/ directory.
* pkg/level#LoadFile:
* Like the doodads.LoadFile, tries from built-in bindata first, then
ajax request (WASM) before accessing the filesystem (desktop)
* Menu Scene: TODO, list the built-in levels in the Load Level menu.
This feature will soon go away when WASM gets its own storage for user
levels (localStorage instead of filesystem)
* 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.
* 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!)
* To the MenuScene add the "Load Drawing" window UI.
* Displays the user's Levels and Doodads using rows of buttons, 4
buttons per row. Clicking the button loads the EditorScene with that
filename.
* Free Version does not display the Doodads label or button on this
menu screen.
Add the ability to drag and drop Doodads onto the level. The Doodad
buttons on the palette now trigger a Drag/Drop behavior when clicked,
and a "blueprint colored" version of the Doodad follows your cursor,
centered on it.
Actors are assigned a random UUID ID when they are placed into a level.
The Canvas gained a MaskColor property that forces all pixels in the
drawing to render as the same color. This is a visual-only effect, and
is used when dragging Doodads in so they render as "blueprints" instead
of their actual colors until they are dropped.
Fix the chunk bitmap cache system so it saves in the $XDG_CACHE_FOLDER
instead of /tmp and has better names. They go into
`~/.config/doodle/chunks/` and have UUID file names -- but they
disappear quickly! As soon as they are cached into SDL2 they are removed
from disk.
Other changes:
- UI: Add Hovering() method that returns the widgets that are beneath
a point (your cursor) and those that are not, for easy querying
for event propagation.
- UI: Add ability to return an ErrStopPropagation to tell the master
Scene (outside the UI) not to continue sending events to other
parts of the code, so that you don't draw pixels during a drag
event.
Add the JSON format for embedding Actors (Doodad instances) inside of a
Level. I made a test map that manually inserted a couple of actors.
Actors are given to the Canvas responsible for the Level via the
function `InstallActors()`. So it means you'll call LoadLevel and then
InstallActors to hook everything up.
The Canvas creates sub-Canvas widgets from each Actor.
After drawing the main level geometry from the Canvas.Chunker, it calls
the drawActors() function which does the same but for Actors.
Levels keep a global map of all Actors that exist. For any Actors that
are visible within the Viewport, their sub-Canvas widgets are presented
appropriately on top of the parent Canvas. In case their sub-Canvas
overlaps the parent's boundaries, their sub-Canvas is resized and moved
appropriately.
- Allow the MainWindow to be resized at run time, and the UI
recalculates its sizing and position.
- Made the in-game Shell properties editable via environment variables.
The kirsle.env file sets a blue and pink color scheme.
- Begin the ground work for Levels and Doodads to embed files inside
their data via the level.FileSystem type.
- UI: Labels can now contain line break characters. It will
appropriately render multiple lines of render.Text and take into
account the proper BoxSize to contain them all.
- Add environment variable DOODLE_DEBUG_ALL=true that will turn on ALL
debug overlay and visualization options.
- Add debug overlay to "tag" each Canvas widget with some of its
details, like its Name and World Position. Can be enabled with the
environment variable DEBUG_CANVAS_LABEL=true
- Improved the FPS debug overlay to show in labeled columns and multiple
colors, with easy ability to add new data points to it.