The gamepad mouse cursor has become THE mouse cursor. It is always visible and your
real cursor is hidden, and this way the game can swap out other cursors for certain
scenarios:
* The Pencil Tool in the editor will use a pencil cursor over the level canvas.
* The Flood Tool has a custom Flood cursor so you don't forget it's selected!
Other improvements:
* The Palette buttons in the editor now render using their swatch's pattern
instead of only using its color.
* If you have an ultra HD monitor and open a Bounded level in the editor which
is too small to fill your screen, the editor canvas limits its size to fit
the level (preferable over showing parts of the level you can't actually play
as it's out of bounds).
* The "brush size" box is only drawn around the cursor when a relevant tool is
selected (Pencil, Line, Rect, Ellipse, Eraser)
* New built-in wallpaper: "Dotted paper (dark)" is a dark-themed wallpaper.
* New built-in palette: "Neon Bright" with bright colors for dark levels.
* New cheat: "warp whistle" to automatically win the level.
* In case the user has a VERY LARGE screen resolution bigger than the full
bounds of a Bounded level, the Play Scene will cap the size and center
the level canvas onto the window. This is preferable to being able to see
beyond the level's boundaries and hitting an invisible wall in-game.
* Make the titlescreen Lazy Scroll work on unbounded levels. It can't bounce
off scroll boundaries but it will reverse course if it reaches the level's
furthest limits.
* Bugfix: characters' white eyes were transparent in-game. Multiple culprits
from the `doodad convert` tool defaulting the chroma key to white, to the
SDL2 textures considering white to be transparent. For the latter, the game
offsets the color by -1 blue.
* Editor: Auto-save on a background goroutine so you don't randomly freeze
the editor up during.
* Fix actor linking issues when you drag and re-place a linked doodad: the
level was too eagerly calling PruneLinks() whenever a doodad was 'destroyed'
(such as the one just picked up) breaking half of the link connection.
* Chunk unloader: do not unload a chunk that has been modified (Set or Delete
called on), keep them in memory until the next ZIP file save to flush them
out to disk.
* Link Tool: if you clicked an actor and don't want to connect a link, click
the first actor again to de-select it.
Updates to the `doodad` tool:
* `doodad edit-level --resize <int>` can re-chunk a level to use a different
chunk size than the default 128. Large chunk sizes 512+ lead to performance
problems.
Especially to further optimize memory for large levels, Levels and
Doodads can now read and write to a ZIP file format on disk with
chunks in external files within the zip.
Existing doodads and levels can still load as normal, and will be
converted into ZIP files on the next save:
* The Chunker.ChunkMap which used to hold ALL chunks in the main json/gz
file, now becomes the cache of "hot chunks" loaded from ZIP. If there is
a ZIP file, chunks not accessed recently are flushed from the ChunkMap
to save on memory.
* During save, the ChunkMap is flushed to ZIP along with any non-loaded
chunks from a previous zipfile. So legacy levels "just work" when
saving, and levels loaded FROM Zip will manage their ChunkMap hot
memory more carefully.
Memory savings observed on "Azulian Tag - Forest.level":
* Before: 1716 MB was loaded from the old level format into RAM along
with a slow load screen.
* After: only 243 MB memory was used by the game and it loaded with
a VERY FAST load screen.
Updates to the F3 Debug Overlay:
* "Chunks: 20 in 45 out 20 cached" shows the count of chunks inside the
viewport (having bitmaps and textures loaded) vs. chunks outside which
have their textures freed (but data kept), and the number of chunks
currently hot cached in the ChunkMap.
The `doodad` tool has new commands to "touch" your existing levels
and doodads, to upgrade them to the new format (or you can simply
open and re-save them in-game):
doodad edit-level --touch ./example.level
doodad edit-doodad --touch ./example.doodad
The output from that and `doodad show` should say "File format: zipfile"
in the headers section.
To do:
* File attachments should also go in as ZIP files, e.g. wallpapers
Adds support for Xbox and Nintendo style game controllers. The gamepad
controls are documented on the README and in the game's Settings window.
The buttons are not customizable yet, except that the player can choose
between two button styles:
* X Style (default): "A" button is on the bottom and "B" on the right.
* N Style: swaps the A/B and the X/Y buttons to use a Nintendo-style
layout instead of an Xbox-style.
The Default handler of the developer command shell now calls out to
RiveScript to match the user's message to a friendly reply. If
RiveScript returns NoReplyMatched then give the "command not found"
error.
* SDL2 builds of the game now set their app window icon.
* Create/Edit Level window is updated to show a tabbed UI to create a
new Level or a new Doodad. The dedicated main menu button to create a
new doodad (which immediately prompted for its size) is replaced by
this new tab's UI.
* Edit Drawing/Play Level window is more responsive to smaller screen
sizes by drawing fewer columns of filenames.
* Bugfix: the Alert and Confirm modals always re-center themselves on
screen, especially to adapt between Portrait or Landscape mode on a
mobile device.
Adds `doodad levelpack create` and `doodad levelpack show` commands to
the CLI tool to create levelpacks.
A levelpack is a ZIP file containing a descriptive index.json and
directories for levels and doodads.
* The level scroll logic was getting a null pointer crash if you open a
doodad rather than a level file.
* Add a crosshair option to the level editor, configurable in the Game
Settings window.
* Recolor some of the region doodads
* Add command: `doodad edit-level --remove-actor` to remove actors from
your level.
* Tweak the player jump velocity from playtesting levels.
Improvements to the Zoom feature:
* Actor position and size within your level scales up and down
appropriately. The canvas size of the actor is scaled and its canvas
is told the Zoom number of the parent so it will render its own
graphic scaled correctly too.
Other features:
* "Experimental" tab added to the Settings window as a UI version of the
--experimental CLI option. The option saves persistently to disk.
* The "Replace Palette" experimental feature now works better. Debating
whether it's a useful feature to even have.
* 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
* 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.
* 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.
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`
* The --chdir CLI option to doodle will set a working directory for the
game to switch to on startup. Flatpak builds place the files at
/app/share/doodle where the ./rtp and ./guidebook files are relative
to and this allows the game to find its sound effects and such.
* 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.
* 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.
* Added a --window flag to the game executable to specify the startup
window resolution. Either specify an exact size (e.g. 1024x768) or a
special keyword "desktop", "mobile" or "landscape"
* Default size is "desktop" or 1024x768
* Mobile simulates a smartphone form factor of 375x812
* Landscape is mobile but flipped horizontally.
* Doodle UX isn't great on mobile but this is a step towards working on
mobile friendly UI
Adds support for sound effects in Doodle and configures some for various
doodads to start out with:
* Buttons and Switches: "Clicked down" and "clicked up" sounds.
* Colored Doors: an "unlocked" sound and a "door opened" sound.
* Electric Door: sci-fi sounds when opening and closing.
* Keys: sound effect for collecting keys.
JavaScript API for Doodads adds a global function `Sound.Play(filename)`
to play sounds. All sounds in the `rtp/sfx/` folder are pre-loaded on
startup for efficient use in the app. Otherwise sounds are lazy-loaded
on first playback.
* 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
* The `doodad edit-doodad` command now allows setting custom key/value
tags in doodad files, for extra data storage useful to their scripts.
* Colored keys and doors now store a `color` tag with the appropriate
color so that their scripts don't have to parse their Title to find
that information.
* Trapdoors now store a `direction` tag to hold the direction the door
is facing.
Add new doodads:
* Start Flag: place this in a level to set the spawn point of the player
character. If no flag is found, the player spawns at 0,0 in the top
corner of the map. Only use one Start Flag per level, otherwise the
player will randomly spawn at one of them.
* Crumbly Floor: a solid floor that begins to shake and then fall apart
after a moment when a mobile character steps on it. The floor respawns
after 5 seconds.
* State Blocks: blue and orange blocks that toggle between solid and
pass-thru whenever a State Button is activated.
* State Button: a solid "ON/OFF" block that toggles State Blocks back
and forth when touched. Only activates if touched on the side or bottom;
acts as a solid floor when walked on from the top.
New features for doodad scripts:
* Actor scripts: call SetMobile(true) to mark an actor as a mobile mob
(i.e. player character or enemy). Other doodads can check if the actor
colliding with them IsMobile so they don't activate if placed too close
to other (non-mobile) doodads in a level. The Blue and Red Azulians
are the only mobile characters so far.
* Message.Broadcast allows sending a pub/sub message out to ALL doodads
in the level, instead of only to linked doodads as Message.Publish does.
This is used for the State Blocks to globally communicate on/off status
without needing to link them all together manually.
* The `doodad` CLI tool got a lot of new commands:
* `doodad show` to verbosely print details about Levels and Doodads.
* `edit-level` and `edit-doodad` to update details about Levels and
Doodads, such as their Title, Author, page type and size, etc.
* Doodads gain a `Hidden bool` that hides them from the palette in
Editor Mode. The player character (Blue Azulian) is Hidden.
* Add some boolProps to the balance/ package and made a dynamic system
to easily configure these with the in-game dev console.
* Command: `boolProp list` returns available balance.boolProps
* `boolProp <name>` returns the current value.
* `boolProp <name> <true or false>` sets the value.
* The new boolProps are:
* showAllDoodads: enable Hidden doodads on the palette UI (NOTE:
reload the editor to take effect)
* writeLockOverride: edit files that are write locked anyway
* prettyJSON: pretty-format the JSON files saved by the game.
* Load SDL2 fonts from go-bindata storage so we don't have to ship
external font files on disk.
* Dedupe names of doodads so we don't show double on the front-end
(go-bindata bundled doodads + those on local filesystem)
* Use go-bindata for accessing wallpaper images.
* Better flashed messages walking you through the Link Tool.
* Stylize the title screen (MainScene) by rendering a live example level
as the background wallpaper, with mobile doodads in motion.
* Add sync.WaitGroup to some parts of the level collision detection
function and Canvas.Loop() to speed up the frame rate by load
balancing some work in parallel across multiple cores.
* Improves FPS from 30 to 55+ even for busy scenes with lots of mobile
enemies walking around.
* Before the level collision optimization, framerate would sometimes dip
to 30 FPS simply to move the player character on a completely blank
map!
* Add animation support for Doodad actors (Play Mode) into the core
engine, so that the Doodad script can register named animations and
play them without managing all the details themselves.
* Doodad API functions on Self: AddAnimation, PlayAnimation,
StopAnimation, IsAnimating
* CLI: the `doodad convert` command will name each layer after the
filename used as the input image.
* CLI: fix the `doodad convert` command creating duplicate Palette
colors when converting a series of input images into a Doodad.
* 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.
* CLI: fix the `doodad convert` command to share the same Palette when
converting each frame (layer) of a doodad so subsequent layers find
the correct color swatches for serialization.
* Scripting: add timers and intervals to Doodad scripts to allow them to
animate themselves or add delayed callbacks. The timers have the same
API as a web browser: setTimeout(), setInterval(), clearTimeout(),
clearInterval().
* Add support for uix.Actor to change its currently rendered layer in
the level. For example a Button Doodad can set its image to Layer 1
(pressed) when touched by the player, and Trapdoors can cycle through
their layers to animate opening and closing.
* Usage from a Doodad script: Self.ShowLayer(1)
* Default Doodads: added scripts for all Buttons, Doors, Keys and the
Trapdoor to run their various animations when touched (in the case of
Keys, destroy themselves when touched, because there is no player
inventory yet)
* Improve the `doodad convert` command to convert a series of input
images into multiple Frames of a Doodad:
`doodad convert frame1.png frame2.png frameN.png output.doodad`
* Add the initial round of dev-asset sprites for the default Doodads:
* Button, Button-TypeB and Sticky Button
* Red, Blue, Green and Yellow Locked Doors and Keys
* Electric Door
* Trapdoor Down
* Add dev-assets/palette.json that defines our default doodad color
palette. Eventually the JSON will be used by the `doodad` tool to give
the layers meaningful names.
* 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.
Implement the Wallpaper system into the levels and the concept of
Bounded and Unbounded levels.
The first wallpaper image is notepad.png which looks like standard ruled
notebook paper. On bounded levels, the top/left edges of the page look
as you would expect and the blue lines tile indefinitely in the positive
directions. On unbounded levels, you only get the repeating blue lines
but not the edge pieces.
A wallpaper is just a rectangular image file. The image is divided into
four equal quadrants to be the Corner, Top, Left and Repeat textures for
the wallpaper. The Repeat texture is ALWAYS used and fills all the empty
space behind the drawing. (Doodads draw with blank canvases as before
because only levels have wallpapers!)
Levels have four options of a "Page Type":
- Unbounded (default, infinite space)
- NoNegativeSpace (has a top left edge but can grow infinitely)
- Bounded (has a top left edge and bounded size)
- Bordered (bounded with bordered texture; NOT IMPLEMENTED!)
The scrollable viewport of a Canvas will respect the wallpaper and page
type settings of a Level loaded into it. That is, if the level has a top
left edge (not Unbounded) you can NOT scroll to see negative coordinates
below (0,0) -- and if the level has a max dimension set, you can't
scroll to see pixels outside those dimensions.
The Canvas property NoLimitScroll=true will override the scroll locking
and let you see outside the bounds, for debugging.
- Default map settings for New Level are now:
- Page Type: NoNegativeSpace
- Wallpaper: notepad.png (default)
- MaxWidth: 2550 (8.5" * 300 ppi)
- MaxHeight: 3300 ( 11" * 300 ppi)
Adds the `doodad` binary which will be a command line tool to work with
Doodads and Levels and assist with development.
The `doodad` binary has subcommands like git and the first command is
`convert` which converts between image files (PNG or BMP) and Doodle
drawing files (Level or Doodad). You can "screenshot" a level into a PNG
or you can initialize a new drawing from a PNG.
* Increase the default window size from 800x600 to 1024x768.
* Move the drawing canvas in EditorMode to inside the EditorUI where it can
be better managed with the other widgets it shares the screen with.
* Slightly fix Frame packing bug (with East orientation) that was causing
right-aligned statusbar items to be partially cropped off-screen. Moved a
couple statusbar labels in EditorMode to the right.
* Add `Parent()` and `Adopt()` methods to widgets for when they're managed
by containers like the Frame.
* Add utility functions to UI toolkit for computing a widget's Absolute
Position and Absolute Rect, by crawling all parent widgets and summing
them up.
* Add `lib/debugging` package with useful stack tracing utilities.
* Add `make guitest` to launch the program into the GUI Test.
The command line flag is: `doodle -guitest`
* Console: add a `close` command which returns to the MainScene.
* Initialize the font cache directory (~/.cache/doodle/fonts) but don't
extract the fonts there yet.
* Create a configuration directory to store the user's local levels
and doodads. On Linux this is at ~/.config/doodle
* Unify the file loading and saving functions: you can type into the
console "edit example" and it will open `example.level` from your
levels folder or else `example.doodad` from the doodads folder, in the
appropriate mode.
* You can further specify the file extension: `edit example.doodad` and
it will load it from the doodads folder only.
* Any slash characters in a file name are taken literally as a relative
or absolute path.
* The UI Save/Load buttons now share the same code path as the console
commands, so the `save` command always saves as a Doodad when the
EditorScene is in Doodad Mode.
Adds the first features to Edit Mode to support creation of Doodad
files! The "New Doodad" button pops up a prompt for a Doodad size
(default 100px) and configures the Canvas widget and makes a Doodad
struct instead of a Level to manage.
* Move the custom Canvas widget from `level.Canvas` to `uix.Canvas`
(the uix package is for our custom UI widgets now)
* Rename the `doodads.Doodad` interface (for runtime instances of
Doodads) to `doodads.Actor` and make `doodads.Doodad` describe the
file format and JSON schema instead.
* Rename the `EditLevel()` method to `EditDrawing()` and it inspects the
file extension to know whether to launch the Edit Mode for a Level or
for a Doodad drawing.
* Doodads can be edited by using the `-edit` CLI flag or using the
in-game file open features (including `edit` command of dev console).
* Add a `Scrollable` boolean to uix.Canvas to restrict the keyboard
being able to scroll the level, for editing Doodads which have a fixed
size.