Doodle is the game engine for Sketchy Maze written in Go. https://www.sketchymaze.com/
Go to file
Noah Petherbridge 279a980106 WIP Texture Caching
NOTICE: Chunk size set to 100 for visual testing!
NOTICE: guitest references a bmp file that isn't checked in!

BUGS REMAINING:
- When scrolling the level in Edit Mode, some of the chunks will pop
  out of existence randomly.
- When clicking-dragging to draw in Edit Mode, if the scroll position
  is not at 0,0 then the pixels drawn will be offset from the cursor.
- These are to do with the Scroll position and chunk coordinate calc
  functions probably.

Implements a texture caching interface to stop redrawing everything
pixel by pixel on every frame.

The texture caching workflow is briefly:

- The uix.Canvas widget's Present() function iterates over the list of
  Chunk Coordinates that are visible inside of the current viewport
  (i.e. viewable on screen)
- For each Chunk:
  - Make it render and/or return its cached Texture object.
  - Work out how much of the Chunk will be visible and how to crop the
    boxes for the Copy()
  - Copy the cached Texture instead of drawing all the pixels every
    time like we were doing before.
- The Chunk.Texture() function that returns said Texture:
  - It calls Chunk.ToBitmap() to save a bitmap on disk.
  - It calls Engine.NewBitmap() to get a Texture it can hang onto.
  - It hangs onto the Texture and returns it on future calls.
  - Any call to Set() or Delete() a pixel will invalidate the cache
    (mark the Chunk "dirty") and Texture() will rebuild next call.

The interface `render.Texturer` provides a way for rendering backends
(SDL2, OpenGL) to transport a "texture" of their own kind without
exposing the type details to the user.

The interface `render.Engine` adds two new methods:

* NewBitmap(filename string) (Texturer, error)
* Copy(t Texturer, src, dst Rect)

NewBitmap should open a bitmap image on disk and return it wrapped in a
Texturer (really it's an SDL2 Texture). This is for caching purposes.
Next the Copy() function blits the texture onto the screen renderer
using the source and destination rectangles.

The uix.Canvas widget orchestrates the caching for the drawing it's
responsible for. It queries which chunks are viewable in the Canvas
viewport (scroll and bounding boxes), has each chunk render out their
entire bitmap image to then cache them as SDL textures and then only
_those_ need to be copied out to the renderer each frame.

The frame rate now sits at a decent 60 FPS even when the drawing gets
messy and full of lines. Each unique version of each chunk needs to
render only one time and then it's a fast copy operation for future
ticks.

Other changes:

- Chunker now assigns each Chunk what their coordinate and size are, so
  that the chunk can self reference that information. This info is
  considered read-only but that isn't really enforced.
- Add Chunker.IterViewportChunks() that returns a channel of Chunk
  Coordinates that are visible in your viewport, rather than iterating
  over all of the pixels in all of those chunks.
- Add Chunk.ToBitmap(filename) that causes a Chunk to render its pixels
  to a bitmap image on disk. SDL2 can natively speak Bitmaps for texture
  caching. Currently these go to files in /tmp but will soon go into your
  $XDG_CACHE_FOLDER instead.
- Add Chunk.Texture() that causes a Chunk to render and then return a
  cached bitmap texture of the pixels it's responsible for. The texture
  is cached until the Chunk is next modified with Set() or Delete().
- UI: add an Image widget that currently just shows a bitmap image. It
  was the first test for caching bitmap images for efficiency. Can show
  any *.bmp file on disk!
- Editor UI: make the StatusBar boxes dynamically build from an array
  of string pointers to make it SUPER EASY to add/remove labels.
2018-10-17 20:52:44 -07:00
balance WIP Texture Caching 2018-10-17 20:52:44 -07:00
cmd Add doodad.exe binary and PNG to Drawing Converter 2018-10-16 12:26:41 -07:00
docs Check in updated docs before break 2018-08-22 10:01:02 -07:00
doodads Doodad Edit Mode: Saving and Loading From Disk 2018-09-26 10:07:22 -07:00
draw Basic Collision Detection, Toggle Between Play/Edit 2018-07-23 20:10:53 -07:00
enum Fix Play Mode, Level Handover & Collision Detection 2018-09-25 09:40:34 -07:00
events Abstract Drawing Canvas into Reusable Widget 2018-08-16 20:37:19 -07:00
level WIP Texture Caching 2018-10-17 20:52:44 -07:00
lib/debugging Move Editor Canvas Into UI + UI Improvements 2018-10-08 10:38:49 -07:00
render WIP Texture Caching 2018-10-17 20:52:44 -07:00
types Save and restore maps as JSON files 2018-06-17 10:31:44 -07:00
ui WIP Texture Caching 2018-10-17 20:52:44 -07:00
uix WIP Texture Caching 2018-10-17 20:52:44 -07:00
.editorconfig Initial commit 2017-10-26 18:03:11 -07:00
.gitignore Add Palette Window and Palette Support to Edit Mode 2018-08-10 17:19:47 -07:00
Changes.md Milestone: Screenshot to PNG Test Feature 2018-06-17 07:56:51 -07:00
commands.go Add Initial "Doodad Palette" UX 2018-10-08 13:06:42 -07:00
config.go Add Initial "Doodad Palette" UX 2018-10-08 13:06:42 -07:00
Debug Notes.md Add JS + History to Shell, Add Main Scene 2018-07-25 19:38:54 -07:00
doodle.go Move Editor Canvas Into UI + UI Improvements 2018-10-08 10:38:49 -07:00
editor_scene_debug.go Move Editor Canvas Into UI + UI Improvements 2018-10-08 10:38:49 -07:00
editor_scene.go Move Editor Canvas Into UI + UI Improvements 2018-10-08 10:38:49 -07:00
editor_ui.go WIP Texture Caching 2018-10-17 20:52:44 -07:00
fps.go Doodad Edit Mode: Saving and Loading From Disk 2018-09-26 10:07:22 -07:00
guitest_scene.go WIP Texture Caching 2018-10-17 20:52:44 -07:00
Ideas.md Check in updated docs before break 2018-08-22 10:01:02 -07:00
log.go Implement Chunk System for Pixel Data 2018-09-23 15:42:05 -07:00
main_scene.go Abstract Drawing Canvas into Reusable Widget 2018-08-16 20:37:19 -07:00
Makefile Add doodad.exe binary and PNG to Drawing Converter 2018-10-16 12:26:41 -07:00
play_scene.go Doodad Edit Mode: Saving and Loading From Disk 2018-09-26 10:07:22 -07:00
README.md Add doodad.exe binary and PNG to Drawing Converter 2018-10-16 12:26:41 -07:00
scene.go Add JS + History to Shell, Add Main Scene 2018-07-25 19:38:54 -07:00
shell.go Add Initial "Doodad Palette" UX 2018-10-08 13:06:42 -07:00

Doodle

Doodle is a drawing-based maze game written in Go.

Features

(Eventually), the high-level, user-facing features for the game are:

  • Draw your own levels freehand and then play them like a 2D platformer game.
  • In Adventure Mode you can play through a series of official example levels that ship with the game.
  • In Edit Mode you can draw a map freehand-style and lay down physical geometry, and mark which lines are solid or which ones behave like fire.
  • Drag and drop Doodads like buttons, doors and keys into your level and link them together so that buttons open doors and levers activate devices.
  • In Play Mode you can play your level as a 2D platformer game where you collect keys, watch out for enemies, and solve puzzles to get to the exit.
  • Easily Share your custom maps with friends.

Mod-friendly

  • Users can create Custom Doodads to extend the game with a scripting language like JavaScript. The sprites and animations are edited in-game in Edit Mode, but the scripting is done in your text editor.
  • In Edit Mode you can drag custom doodads into your maps.
  • To Share your maps, you can choose to bundle the custom doodads inside your map file itself, so that other players can play the map without needing to install the doodads separately.
  • If you receive a map with custom doodads, you can install the doodads into your copy of the game and use them in your own maps.

Keybindings

Global Keybindings:

Escape
  Close the developer console if open, without running any commands.
  Exit the program otherwise.

Enter
  Open and close the developer console, and run commands while the console
  is open.

In Play Mode:

Cursor Keys
  Move the player around.

In Edit Mode:

F12
  Take a screenshot (generate a PNG based on level data)

Developer Console

Press Enter at any time to open the developer console.

Commands supported:

new
  Create a new map in Edit Mode.

save [filename.json]
  Save the current map in Edit Mode. The filename is required if the map has
  not been saved yet.

edit [filename.json]
  Open a map in Edit Mode.

play [filename.json]
  Open a map in Play Mode.

echo <text>
  Flash a message to the console.

clear
  Clear the console output history.

exit
quit
  Close the developer console.

Milestones

As a rough idea of the milestones needed for this game to work:

SDL Paint Program

  • Create a basic SDL window that you can click on to color pixels.
    • Connect the pixels while the mouse is down to cover gaps.
  • Implement a "screenshot" button that translates the canvas to a PNG image on disk.
    • F12 key to take a screenshot of your drawing.
    • It reproduces a PNG image using its in-memory knowledge of the pixels you have drawn, not by reading the SDL canvas. This will be important for making the custom level format later.
    • The PNG I draw looks slightly different to what you see on the SDL canvas; maybe difference between Renderer.DrawLine() and my own algorithm or the anti-aliasing.
  • Create a custom map file format (protobufs maybe) and "screenshot" the canvas into this custom file format.
  • Make the program able to read this file format and reproduce the same pixels on the canvas.
  • Abstract away SDL logic into a small corner so it can be replaced with OpenGL or something later on.
  • Implement a command line shell in-game to ease development before a user interface is created.
    • Add support for the shell to pop itself open and ask the user for input prompts.

Alpha Platformer

  • Inflate the pixel history from the map file into a full lookup grid of (X,Y) coordinates. This will be useful for collision detection.
  • Create a dummy player character sprite, probably just a render.Circle(). In Play Mode run collision checks and gravity on the player sprite.
    • Create the concept of the Doodad and make the player character implement one.
  • Get basic movement and collision working. With a cleanup this can make a workable ALPHA RELEASE
    • Ability to move laterally along the ground.
    • Ability to walk up reasonable size slopes but be stopped when running against a steeper wall.
    • Basic gravity

UI Overhaul

  • Create a user interface toolkit which will be TREMENDOUSLY helpful for the rest of this program.
    • Labels
    • Buttons (text only is OK)
      • Buttons wrap their Label and dynamically compute their size based on how wide the label will render, plus padding and border.
      • Border colors and widths and paddings are all configurable.
      • Buttons should interact with the cursor and be hoverable and clickable.
    • UI Manager that will keep track of buttons to know when the mouse is interacting with them.
    • Frames
      • Like Buttons, can have border (raised, sunken or solid), padding and background color.
      • Should be able to size themselves dynamically based on child widgets.
    • Windows (fixed, non-draggable is OK)
      • Title bar with label
      • Window body implements a Frame that contains child widgets.
      • Window can resize itself dynamically based on the Frame.
  • Create a "Main Menu" scene with buttons to enter a new Edit Mode, play an existing map from disk, etc.
  • Add user interface Frames or Windows to the Edit Mode.
    • A toolbar of buttons (New, Save, Open, Play) can be drawn at the top before the UI toolkit gains a proper MenuBar widget.
    • Expand the Palette support in levels for solid vs. transparent, fire, etc. with UI toolbar to choose palettes.
  • Add a "Canvas" widget that will hold level drawing data and abstract it out such that the Canvas can have a constrained width and height, position, and "scrollable" viewport area that determines rendered pixels. Will be VERY useful for Doodads and working on levels smaller than your window size (like doodads).

Lesser important UI features that can come at any later time:

  • MenuBar widget with drop-down menu support.
  • Checkbox and Radiobox widgets.
  • Text Entry widgets (in the meantime use the Developer Shell to prompt for text input questions)

Doodad Editor

  • The Edit Mode should support creating drawings for Doodads.
    • It should know whether you're drawing a Map or a Doodad as some behaviors may need to be different between the two.
    • Compress the coordinates down toward (0,0) when saving a Doodad, by finding the toppest, leftest point and making that (0,0) and adjusting the rest accordingly. This will help trim down Doodads into the smallest possible space for easy collision detection.
    • Add a UX to edit multiple frames for a Doodad.
    • Edit Mode should be able to fully save the drawings and frames, and an external CLI tool can install the JavaScript into them.
    • Possible UX to toggle Doodad options, like its collision rules and whether the Doodad is continued to be "mobile" (i.e. doors and buttons won't move, but items and enemies may be able to; and non-mobile Doodads don't need to collision check against level geometry).
  • Edit Mode should have a Doodad Palette (Frame or Window) to drag Doodads into the map.
  • ???

Building

Fedora dependencies:

$ sudo dnf install SDL2-devel SDL2_ttf-devel

Fonts

The fonts/ folder is git-ignored. The app currently uses font files here named:

  • DejaVuSans.ttf for sans-serif font.
  • DejaVuSans-Bold.ttf for bold sans-serif font.
  • DejaVuSansMono.ttf for monospace font.

These are the open source DejaVu Sans [Mono] fonts, so copy them in from your /usr/share/fonts/dejavu folder or provide alternative fonts.

mkdir fonts
cp /usr/share/fonts/dejavu/{DejaVuSans.ttf,DejaVuSans-Bold.ttf,DejaVuSansMono.ttf} fonts/