Commit Graph

67 Commits (master)

Author SHA1 Message Date
Noah a06787411d Resolve circular import errors for Doodle++ plugin
* pkg/plus/dpp is the main plugin bridge, and defines nothing but an interface
  that defines the Doodle++ surface area (referring to internal game types such
  as doodad.Doodad or level.Level), but not their implementations.
  * dpp.Driver (an interface) is the main API that other parts of the game will
    call, for example "dpp.Driver.IsLevelSigned()"
  * plus_dpp.go and plus_foss.go provide the dpp.Driver implementation for their
    build; with plus_dpp.go generally forwarding function calls directly to the
    proprietary dpp package and plus_foss.go generally returning false/errors.
  * The bootstrap package simply assigns the above stub function to dpp.Driver
* pkg/plus/bootstrap is a package directly imported by main (in the doodle and
  doodad programs) and it works around circular dependency issues: this package
  simply assigns dpp.Driver to the DPP or FOSS version.

Miscellaneous fixes:

* File->Open in the editor and PlayScene will use the new Open Level window
  instead of loading the legacy GotoLoadMenu scene.
* Deprecated legacy scenes: d.GotoLoadMenu() and d.GotoPlayMenu().
* The doodle-admin program depends on the private dpp package, so can not be
  compiled in FOSS mode.
2024-04-18 22:12:56 -07:00
Noah 7eb7f6148c WIP Doodle++ 2024-04-18 20:23:07 -07:00
Noah 1a9706c09f Level Thumbnails on Story Mode Select
* Rework the Story Mode UI to display level thumbnails.
  * Responsive UI: defaults to wide screen mode and shows 3 levels horizontally
    but on narrow/mobile display, shows 2 levels per page in portrait.
  * Add "Tiny" screenshot size (224x126) to fit the Story Mode UI.
  * Make the pager buttons bigger and more touchable.
* Maximize the game window on startup unless the -w option with a specific
  window resolution is provided.
2023-12-09 14:59:31 -08:00
Noah da83231559 Level Screenshots and Thumbnails
Adds some support for "less giant" level screenshots.

* In the Editor, the Level->Take Screenshot menu will render a cropped screen
  shot of just the level viewport on screen. Note: it is not an SDL2 screen
  copy but generated from scratch from the level data.
* In levels themselves, screenshots can be stored inside the level data in
  three different sizes: large (1280x720), medium and small (each a halved
  size of the previous).
* The first screenshot is created when the level is saved, starting from
  wherever the scroll position in the editor is at, and recording the 720p
  view of the level from there.
* The level screenshot can be previewed and updated in the Level Properties
  window of the editor: so you can scroll the editor to just the right position
  and take a good screenshot to represent your level.
* In the future: these embedded level screenshots will be displayed on the
  Story Mode and other screens to see a preview of each level.

Other tweaks:

* When taking a Giant Screenshot: a confirm modal will warn the player that
  it may take a while. And during the screenshot, show the new Wait Modal to
  block player interaction until the screenshot has finished.
2023-12-08 19:48:02 -08:00
Noah 79996ccd34 ListBoxes Overhaul
* Overhaul the clunky old alpha Edit Level/Doodad menu with a modernized
  version featuring the new ListBox widget.
* The new level loader is a Window that can be spawned from anywhere instead
  of on a dedicated MenuScene.

Updates to doodad scripts:

* Actor.IsOnScreen() checks whether an actor's visual sprite box is on-screen
  in the level viewport. `Self.IsOnScreen()` will check for the current actor.

Other changes

* PlaySound() to deduplicate the same sound effect from playing at once.
2023-04-08 21:26:08 -07:00
Noah cf1bc81f25 Update savegame format, Allow out-of-bounds camera
Updates the savegame.json file format:

* Levels now have a UUID value assigned at first save.
* The savegame.json will now track level completion/score based on UUID,
making it robust to filename changes in either levels or levelpacks.
* The savegame file is auto-migrated on startup - for any levels not
found or have no UUID, no change is made, it's backwards compatible.
* Level Properties window adds an "Advanced" tab to show/re-roll UUID.

New JavaScript API for doodad scripts:

* `Actors.CameraFollowPlayer()` tells the camera to return focus to the
  player character. Useful for "cutscene" doodads that freeze the player,
  call `Self.CameraFollowMe()` and do a thing before unfreezing and sending the
  camera back to the player. (Or it will follow them at their next directional
  input control).
* `Self.MoveBy(Point(x, y int))` to move the current actor a bit.

New option for the `doodad` command-line tool:

* `doodad resave <.level or .doodad>` will load and re-save a drawing, to
  migrate it to the newest file format versions.

Small tweaks:

* On bounded levels, allow the camera to still follow the player if the player
  finds themselves WELL far out of bounds (40 pixels margin). So on bounded
  levels you can create "interior rooms" out-of-bounds to Warp Door into.
* New wallpaper: "Atmosphere" has a black starscape pattern that fades into a
  solid blue atmosphere.
* Camera strictly follows the player the first 20 ticks, not 60 of level start
* If player is frozen, directional inputs do not take the camera focus back.
2023-03-07 21:55:10 -08:00
Noah 82884c79ae Signed Levels and Levelpacks
Add the ability for the free version of the game to allow loading levels that
use embedded custom doodads if those levels are signed.

* Uses the same signing keys as the JWT token for license registrations.
* Levels and Levelpacks can both be signed. So individual levels with embedded
  doodads can work in free versions of the game.
* Levelpacks now support embedded doodads properly: the individual levels in
  the pack don't need to embed a custom doodad, but if the doodad exists in
  the levelpack's doodads/ folder it will load from there instead - for full
  versions of the game OR when the levelpack is signed.

Signatures are computed by getting a listing of embedded assets inside the
zipfile (the assets/ folder in levels, and the doodads/ + levels/ folders
in levelpacks). Thus for individual signed levels, the level geometry and
metadata may be changed without breaking the signature but if custom doodads
are changed the signature will break.

The doodle-admin command adds subcommands to `sign-level` and `verify-level`
to manage signatures on levels and levelpacks.

When using the `doodad levelpack create` command, any custom doodads the
levels mention that are found in your profile directory get embedded into
the zipfile by default (with --doodads custom).
2023-02-18 17:37:54 -08:00
Noah 31097881ff Finalize Non-square Doodads
* Fix display bug with rectangular doodads scrolling off screen.
* The default Author of new files will be your registration name, if available
  before using your $USER name.
2023-02-17 21:09:11 -08:00
Noah ddcad27485 WIP: Chunker size to uint8 and Rectangular Doodads
Convert the Chunker size to a uint8 so chunk sizes are limited to 255px. This
means that inside of a chunk, uint8's can track the relative pixel coordinates
and result in a great memory savings since all of these uint8's are currently
64-bits wide apiece.

WIP on rectangular shaped doodads:
* You can create such a doodad in the editor and draw it normally.
* It doesn't draw the right size when dragged into your level however:
  - In uix.Actor.Size() it gets a rect of the doodad's square Chunker size,
    instead of getting the proper doodad.Size rect.
  - If you give it the doodad.Size rect, it draws the Canvas size correctly
    instead of a square - the full drawing appears and in gameplay its hitbox
    (assuming the same large rectangle size) works correctly in-game.
  - But, the doodad has scrolling issues when it gets to the top or left edge
    of the screen! This old gnarly bug has come back. For some reason square
    canvas doodads draw correctly but rectangular ones have the drawing scroll
    just a bit - how far it scrolls is proportional to how big the doodad is,
    with the Start Flag only scrolling a few pixels before it stops.
2023-02-16 21:47:18 -08:00
Noah a10a09a818 Cheats Menu UI
* Added a Cheats Menu UI accessible from the Settings window's "Experimental"
  tab and from there you can enable the Cheats Menu from the "Help" screen of
  the gameplay mode.
* Commonly used cheats all have corresponding buttons to click on, especially
  helpful for touchscreen devices like the Pinephone where keyboard input
  doesn't always work reliably.
* The buttons in the Cheats Menu just automate entry of the cheat commands.
* `boolProp` command has a new `flip` option to toggle their value (e.g.
  `boolProp show-hidden-doodads flip`)
2023-01-02 12:36:12 -08:00
Noah ecaa8c6cef SemiSolid Pixels + Icons
* Add new pixel attributes: SemiSolid and Slippery (the latter is WIP)
* SemiSolid pixels are only solid below the player character. You can walk on
  them and up and down SemiSolid slopes, but can freely pass through from the
  sides or jump through from below.
* Update the Palette Editor UI to replace the Attributes buttons: instead of
  text labels they now have smaller icons (w/ tooltips) for the Solid,
  SemiSolid, Fire, Water and Slippery attributes.
* Bugfix in Palette Editor: use cropped (24x24) images for the Tex buttons so
  that the large Bubbles texture stays within its designated space!
* uix.Actor.SetGrounded() to also set the Y velocity to zero when an actor
  becomes grounded. This fixes a minor bug where the player's Y velocity (due
  to gravity) was not updated while they were grounded, which may eventually
  become useful to allow them to jump down thru a SemiSolid floor. Warp Doors
  needed a fix to work around the bug, to set the player's Grounded(false) or
  else they would hover a few pixels above the ground at their destination,
  since Grounded status paused gravity calculations.
2022-10-09 21:39:43 -07:00
Noah 701073cecc Doodad/Actor Runtime Options
* Add "Options" support for Doodads: these allow for individual Actor instances
  on your level to customize properties about the doodad. They're like "Tags"
  except the player can customize them on a per-actor basis.
* Doodad Editor: you can specify the Options in the Doodad Properties window.
* Level Editor: when the Actor Tool is selected, on mouse-over of an actor,
  clicking on the gear icon will open a new "Actor Properties" window which
  shows metadata (title, author, ID, position) and an Options tab to configure
  the actor's options.

Updates to the scripting API:

* Self.Options() returns a list of option names defined on the Doodad.
* Self.GetOption(name) returns the value for the named option, or nil if
  neither the actor nor its doodad have the option defined. The return type
  will be correctly a string, boolean or integer type.

Updates to the doodad command-line tool:

* `doodad show` will print the Options on a .doodad file and, when showing a
  .level file with --actors, prints any customized Options with the actors.
* `doodad edit-doodad` adds a --option parameter to define options.

Options added to the game's built-in doodads:

* Warp Doors: "locked (exit only)" will make it so the door can not be opened
  by the player, giving the "locked" message (as if it had no linked door),
  but the player may still exit from the door if sent by another warp door.
* Electric Door & Electric Trapdoor: "opened" can make the door be opened by
  default when the level begins instead of closed. A switch or a button that
  removes power will close the door as normal.
* Colored Doors & Small Key Door: "unlocked" will make the door unlocked at
  level start, not requiring a key to open it.
* Colored Keys & Small Key: "has gravity" will make the key subject to gravity
  and set its Mobile flag so that if it falls onto a button, it will activate.
* Gemstones: they had gravity by default; you can now uncheck "has gravity" to
  remove their Gravity and IsMobile status.
* Gemstone Totems: "has gemstone" will set the totem to its unlocked status by
  default with the gemstone inserted. No power signal will be emitted; it is
  cosmetic only.
* Fire Region: "name" can let you set a name for the fire region similarly to
  names for fire pixels: "Watch out for ${name}!"
* Invisible Warp Door: "locked (exit only)" added as well.
2022-10-09 17:41:24 -07:00
Noah ec0b5ba6ca Rename Go module 2022-09-24 15:17:25 -07:00
Noah 434416d3a4 Spit and polish
* Made the loadscreen useful again (give it work to do async so the game
  doesn't simply freeze during): does a first call to LoadUnloadChunks
  to preload the viewport chunks.
* Hide the mouse cursor when movement keys are pressed.
2022-05-07 18:54:37 -07:00
Noah fc736abd5f Doodads: Gems, Snake and Crusher
Adds several new doodads to the game and 5 new wallpapers (parchment
paper in blue, green, red, white and yellow).

New doodads:

* Crusher: A purple block-headed mob wearing an iron helmet. It tries
  to crush the player when you get underneath. Its flat helmet can be
  ridden on like an elevator back up.
* Snake: A green stationary mob that always faces toward the player.
  If the player is nearby and jumps, the Snake will jump too and hope
  to catch the player in mid-air.
* Gems and Totems: A new key & lock collectible. Gems have quantity so
  you can collect multiple, and place them into matching Totems. A
  Totem gives off a power signal when its gem is placed and all other
  Totems it is linked to have also been activated. A single Totem may
  link to an Electric Door and require only one gem to open it, or it
  can link to other Totems and they all require gems before the power
  signal is sent out.
2022-05-01 15:18:23 -07:00
Noah ad67e2b42b New Doodad: Blue Bird
* The blue bird follows the same base AI as the red bird (it has a
  target altitude that it tries to maintain, and it will dive at the
  player) but the blue bird flies in a sine wave pattern around its
  target altitude. It also has a longer scan radius to search for the
  player than the red bird.
* The sine wave pattern of the blue bird means you may fly under its
  radar depending how high it is on average.

Cheat codes that replace the player character are refactored to make
it easier to extend, and new cheats have been added:

* super azulian: play as the Red Azulian.
* hyper azulian: play as the White Azulian.
* bluebird: play as the new Bird (blue).
2022-04-30 17:59:55 -07:00
Noah db5760ee83 Optimize memory by freeing up SDL2 textures
* Added to the F3 Debug Overlay is a "Texture:" label that counts the number
  of textures currently loaded by the (SDL2) render engine.
* Added Teardown() functions to Level, Doodad and the Chunker they both use
  to free up SDL2 textures for all their cached graphics.
* The Canvas.Destroy() function now cleans up all textures that the Canvas
  is responsible for: calling the Teardown() of the Level or Doodad, calling
  Destroy() on all level actors, and cleaning up Wallpaper textures.
* The Destroy() method of the game's various Scenes will properly Destroy()
  their canvases to clean up when transitioning to another scene. The
  MainScene, MenuScene, EditorScene and PlayScene.
* Fix the sprites package to actually cache the ui.Image widgets. The game
  has very few sprites so no need to free them just yet.

Some tricky places that were leaking textures have been cleaned up:

* Canvas.InstallActors() destroys the canvases of existing actors before it
  reinitializes the list and installs the replacements.
* The DraggableActor when the user is dragging an actor around their level
  cleans up the blueprint masked drag/drop actor before nulling it out.

Misc changes:

* The player character cheats during Play Mode will immediately swap out the
  player character on the current level.
* Properly call the Close() function instead of Hide() to dismiss popup
  windows. The Close() function itself calls Hide() but also triggers
  WindowClose event handlers. The Doodad Dropper subscribes to its close
  event to free textures for all its doodad canvases.
2022-04-09 14:41:24 -07:00
Noah af6b8625d6 Flood Tool, Survival Mode for Azulian Tag
New features:
* Flood Tool for the editor. It replaces pixels of one color with another,
  contiguously. Has limits on how far from the original pixel it will color,
  to avoid infinite loops in case the user clicked on wide open void. The
  limit when clicking an existing color is 1200px or only a 600px limit if
  clicking into the void.
* Cheat code: 'master key' to play locked Story Mode levels.

Level GameRules feature added:
* A new tab in the Level Properties dialog
* Difficulty has been moved to this tab
* Survival Mode: for silver high score, longest time alive is better than
  fastest time, for Azulian Tag maps. Gold high score is still based on
  fastest time - find the hidden level exit without dying!

Tweaks to the Azulians' jump heights:
* Blue Azulian:  12 -> 14
* Red Azulian:   14 -> 18
* White Azulian: 16 -> 20

Bugs fixed:
* When editing your Palette to rename a color or add a new color, it wasn't
  possible to draw with that color until the editor was completely unloaded
  and reloaded; this is now fixed.
* Minor bugfix in Difficulty.String() for Peaceful (-1) difficulty to avoid
  a negative array index.
* Try and prevent user giving the same name to multiple swatches on their
  palette. Replacing the whole palette can let duplication through still.
2022-03-26 13:55:06 -07:00
Noah 647124495b Level Difficulty + UI Polish
Added a new level property: Difficulty

* An enum ranging from -1, 0, 1 (Peaceful, Normal, Hard)
* Default difficulty is Normal; pre-existing levels are Normal by
  default per the zero value.

Doodad scripts can read the difficulty via the new global variable
`Level.Difficulty` and some doodads have been updated:

* Azulians: on Peaceful they ignore all player characters, and on Hard
  they are in "hunt mode": infinite aggro radius and they're aggressive
  to all characters.
* Bird: on Peaceful they will not dive and attack any player character.

Other spit and polish:

* New Level/Level Properties UI reworked into a magicform.
* New "PromptPre(question, answer, func)" function for prompting the
  user with the developer shell, but pre-filling in an answer for them
  to either post or edit.
* magicform has a PromptUser field option for simple Text/Int fields
  which present as buttons, so magicform can prompt and update the
  variable itself.
* Don't show the _autosave.doodad in the Doodad Dropper window.
2022-03-06 22:20:53 -08:00
Noah 44122d4130 Spit and polish
UI improvements specifically for mobile (running the game with the
`-w mobile` or `-w landscape` options) screen sizes.

* Rework the Settings window to be mobile friendly to landscape
  oriented screens (`doodle -w landscape`) and migrate Options tab
  to magicform.
* The toolbar in the Editor will be a single column of buttons
  on small screens, such as `-w mobile` (375x812) portrait mode
  smartphone. On larger screens the toolbar shows in two columns
  of buttons.
* Fix tooltips not drawing on top.
* Centralize the hard-coded references to specific font filenames
* Add cheat code: `test load screen` to bring a sample loading screen up
  for a few seconds. It needs improvement on `-w landscape`
2022-03-05 22:44:54 -08:00
Noah 77297fd60d Text Tool and Pan Tool
Two new tools added to the Level Editor:

* Pan Tool: left-click to scroll the level around safely.
* Text Tool: write text onto your level.

Features of the Text Tool:

* Can choose from the game's built-in fonts, size and enter the message
  you want to write.
* The mouse cursor previews the text when hovered over the level.
* Click to "stamp" the text onto your level. The currently selected
  color swatch will be used to color the text in.
* Adds two new fonts: Azulian.ttf and Rive.ttf that can be selected in
  the Text Tool.

Some implementation notes:

* Added package native/engine_sdl.go that handles the lower-level
  SDL2_TTF logic to rasterize the text into a black&white image.
* WASM not supported yet (if the game even still built for WASM);
  native/engine_wasm.go stubs out the TextToImage() call with a "not
  supported" error just in case.

Other changes:

* New Toolbar icons: they are 24x24 instead of 32x32 to make more room
  for more tools.
* The toolbar now shows two buttons per row for a more densely packed
  layout. For very narrow screen widths (< 600px) the default Vertical
  Toolbar layout will use one-button-per-row to not eat too much screen
  real estate.
* In the Horizontal Toolbars layout there are 2 buttons per column.
2022-03-05 15:34:20 -08:00
Noah 4de0126b19 Game Controller Support
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.
2022-02-19 18:31:22 -08:00
Noah 1cc6eee5c8 Refactor Level Publishing + MagicForm
* magicform is a helper package that may eventually be part of the go/ui
  library, for easily creating structured form layouts.
* The Level Publisher UI is the first to utilize magicform.

Refactor how level publishing works:

* Level data now stores SaveDoodads and SaveBuiltins (bools) and when
  the level editor saves the file, it will attach custom and/or builtin
  doodads just before save.
* Move the menu item from the File menu to Level->Publish
* The Publisher UI just shows the checkboxes to toggle the level
  settings and a convenient Save button along with descriptive text.
* Free versions get the "Register" window popping up if they click the
  Save Now button from within the publisher window.

Note: free versions can still toggle the booleans on/off but their game
will not attach any new doodads on save.

* Free games which open a level w/ embedded doodads will get a pop-up
  warning that the doodads aren't available.
* If they DON'T turn off the SaveDoodads option, they can still edit and
  save the level and keep the existing doodads attached.
* If they UNCHECK the option and save, all attached doodads are removed
  from the level.
2022-01-17 18:51:11 -08:00
Noah 48e18da511 Centralize cheats, detect cheated player character
* If the player runs the PlayAsBird cheat they shouldn't be able to win
  a high score on a level, so at level startup it detects whether the
  DefaultPlayerCharacterDoodad has changed from default on a level that
  doesn't use the Start Flag to set a specific doodad - and immediately
  marks the session as cheated
2022-01-08 18:27:37 -08:00
Noah 9a51ac39f9 Spit and polish
* New doodad: Invisible Warp Door
* All warp doors require the player to be grounded (if affected by
  gravity) to open them. No jumping or falling thru and opening
  a warp door mid-air!
* Title Screen now randomly selects from a couple of levels.
* Title Screen: if it fails to load a level it sets up a basic
  blank level with a wallpaper instead.
* New developer shell command: titlescreen <level>
  Opens the MainScene with a custom user level as the background.
* Add Auto-save to the Editor to save your drawing every 5 minutes
* Add a MenuBar to the Play Scene for easier navigation to other
  features of the game.
* Doodad JS API: time.Since() now available.
2022-01-02 22:36:32 -08:00
Noah 672ee9641a Savegame and High Scores
* 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.
2022-01-02 16:28:43 -08:00
Noah 690fdedb91 Add the ui.ColorPicker 2022-01-01 18:48:34 -08:00
Noah fa5f303dad Bugfix: embedded levelpacks from bindata 2021-12-30 18:39:11 -08:00
Noah d16a8657aa Window Icon, UI Polish
* 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.
2021-12-30 16:31:45 -08:00
Noah 6d3ffcd98c Finalize basic functionality for Level Packs
* 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.
2021-12-26 20:48:29 -08:00
Noah 678326540b WIP LevelPack UI + Landscape Mode Title Screen
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.
2021-12-23 21:11:45 -08:00
Noah ddf0074099 Condensed Palette, Bird AI Update
* The Red Bird now records its original altitude on the level and will
  try and return there should it accidentally climb up or down a wall.
  Sometimes goes into a wavy pattern surrounding its original altitude.
* Editor UI: in the default (vertical) toolbar, the Palette now has a
  two column view to show more color choices on screen at once.
* User setting added: hide the touch control hints.
2021-10-12 20:49:48 -07:00
Noah 0ec259b171 Crosshair Option + Doodad Editor crash fix
* 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.
2021-10-11 15:57:33 -07:00
Noah a112c19d76 Few small tweaks 2021-10-09 21:22:50 -07:00
Noah 1a8a5eb94b Polish and bugfixes
- Fix a memory sharing bug in the Giant Screenshot feature.
- Main Menu to eagerload chunks in the background to make scrolling less
  jittery. No time for a loadscreen!
- Extra script debugging: names/IDs of doodads are shown when they send
  messages to one another.
- Level Properties: you can edit the Bounded max width/height values for
  the level.

Doodad changes:

- Buttons: fix a timing bug and keep better track of who is stepping on it,
  only popping up when all colliders have left. The effect: they pop up
  immediately (not after 200ms) and are more reliable.
- Keys: zero-qty keys will no longer put themselves into the inventory of
  characters who already have one except for the player character. So
  the Thief will not steal them if she already has the key.

Added to the JavaScript API:

* time.Hour, time.Minute, time.Second, time.Millisecond, time.Microsecond
2021-10-09 20:45:38 -07:00
Noah 0b0af70a62 Viewport Windows, Quality of Life, Spit and Polish
* New keybind: 'v' to open a new Viewport in the Level Editor.
* New keybind: Backspace to close the topmost UI window,
  and Shift+Backspace to close them all.
* Zoom has graduated out of experimental feature status. Still a bit
  buggy but workable.
* Viewport windows now copy the Tool and BrushSize of the toplevel
  editor, so drawing in and out of viewports works well.
* Viewport window UI improved: buttons to grow or shrink the window
  size, refresh the actors, etc.
2021-10-06 22:22:34 -07:00
Noah 1f83300cec Picture-in-Picture Window (WIP)
In the Level Editor, the "Level->New viewport" menu opens a window with
its own view into your level. You can open as many viewports as you
want.

* Mouse over a viewport and the arrow keys scroll that canvas instead of
  the main editor canvas!
* You can draw inside the viewports! A selectbox to choose the tool to
  draw with. No palette or thickness support yet!
* The actors are installed as-is when the viewport is created and it
  doesn't show any changes to actors after. Make a new viewport for a
  refreshed view.
* Strokes committed inside the viewport show up in the main editor (and
  in other viewports), and vice versa. The viewports accurately track
  changes to the level's colors, just not the actors.
* Fun feature to load a DIFFERENT level inside of the viewport! Editing
  that level doesn't save changes or anything.
2021-10-03 21:18:39 -07:00
Noah 97e179716c Add Technical Doodads + UI Fixes
New category for the Doodad Dropper: "Technical"

Technical doodads have a dashed outline and label for now, and they
turn invisible on level start, and are for hidden technical effects on
your level.

The doodads include:

* Goal Region: acts like an invisible Exit Flag (128x128), the level is
  won when the player character touches this region.
* Fire Region: acts like a death barrier (128x128), kills the player
  when a generic "You have died!" message.
* Power Source: on level start, acts like a switch and emits a
  power(true) signal to all linked doodads. Link it to your Electric
  Door for it to be open by default in your level!
* Stall Player (250ms): The player is paused for a moment the first time
  it touches this region. Useful to work around timing issues, e.g.
  help prevent the player from winning a race against another character.

There are some UI improvements to the Doodad Dropper window:

* If the first page of doodads is short, extra spacers are added so the
  alignment and size shows correctly.
* Added a 'background pattern' to the window: any unoccupied icon space
  has an inset rectangle slot.
* "Last pages" which are short still render weirdly without reserving
  the correct height in the TabFrame.

Doodad scripting engine updates:

* Self.Hide() and Self.Show() available.
* Subscribe to "broadcast:ready" to know when the level is ready, so you
  can safely Publish messages without deadlocks!
2021-10-02 20:52:16 -07:00
Noah 0a8bce708e Actor Zoom + Experimental Settings GUI
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.
2021-09-11 21:18:22 -07:00
Noah 449a30dc2c Small typo fix 2021-09-03 21:45:48 -07:00
Noah 7866f618da First-class Doodad Hitboxes + Generic Item Script
A new property is added to the Doodad struct: Hitbox (Rect).

The uix.Actor for Play Mode will defer to the Doodad.Hitbox until the
JavaScript has manually set its own via Self.SetHitbox(). So in effect,
scripts no longer need to worry about their hitbox! The one assigned to
the Doodad will be the default.

Scripts can check if their hitbox is zero before setting a default:

  if (Self.Hitbox().IsZero()) {
    var size = Self.Size()           // get doodad canvas size
    Self.SetHitbox(0, 0, size, size) // the full square
  }

The built-in generic doodad scripts have made this change, so that your
simple doodad can have a custom hitbox defined easily using in-game
tools.

Other changes:

* New script: Generic Collectible Item. Selecting it will add a
  "quantity" tag to your doodad, to easily configure the script.
* JavaScript API: "Self.Hitbox()" returns your doodad's current hitbox.
  You can check "Self.Hitbox.IsZero()" to check if it's empty.
2021-09-03 20:39:44 -07:00
Noah 7ea86b4ffc Generic Doodad Script Selection
In the Doodad Properties window, instead of browsing to select a .js
file to install your script, a SelectBox of built-in generic scripts are
available. These scripts implement simple behaviors and adapt to the
full canvas size of the doodad.

Built-in scripts so far include:

* generic-anvil.js: behaves just like the Anvil.
* generic-fire.js: the entire canvas hitbox acts like fire pixels,
  "burning" mobile doodads and failing the level for the player.
* generic-solid.js: the entire canvas hitbox acts solid
2021-09-02 22:33:28 -07:00
Noah 0fa1bf8a76 Editor: Doodad Properties Window
The Doodad Properties window brings many features that used to be
available only in the `doodad` CLI tool into the Doodad Editor.

* In the Doodad Editor there is a new menubar item: "Doodad" which
  corresponds to the "Level" menu when you're editing a level.
* The "Doodad" menu has two items:
  - "Doodad Properties" (NEW)
  - "Layers" (moved here from the Tools menu)
* The Doodad Properties window lets you edit the Title and Author values
  of the doodad, as well as modify its Tags and manage its Script.
* Its script can be attached (browse for .js file on disk), its existing
  script saved back to disk (dev shell prompt) or deleted altogether
  from the doodad.
* You can create, modify, and delete Tags on the doodad.

Other changes:

* In the Level Editor, the "Level->Page Settings" menu is renamed to
  "Level->Level Properties" to match with "Doodad->Doodad Properties"
  and the pop-up window is retitled accordingly.
* The Exit Flag only exits if the Player touches it - not just any
  mobile doodad!
2021-09-02 21:26:55 -07:00
Noah 0cc1d17f4f Sort levels and doodads in the Open menu 2021-08-15 20:27:05 -07:00
Noah 49876c4fdf New TabFrame Widget for Doodads and Settings
* 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.
2021-07-25 21:46:55 -07:00
Noah 26b1ac88dd Shift to scroll slowly + Doodads on Q
* 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.
2021-07-13 18:04:25 -07:00
Noah 99c93dc174 Fix Profile Directory file:// URI for Windows 2021-06-20 13:21:47 -07:00
Noah 386e0b2b0c Brighten Patterns + Update Default Palettes
* 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.
2021-06-20 10:42:51 -07:00
Noah 864156da53 Settings Window + Bugfix
* 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.
2021-06-19 22:14:41 -07:00
Noah dce32ea14b Diverge Free vs. Paid Features
* 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.
2021-06-16 22:35:01 -07:00