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
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.
* 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.
* 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.
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.