diff --git a/dev-assets/guidebook/Makefile b/dev-assets/guidebook/Makefile deleted file mode 100644 index 95ca53b..0000000 --- a/dev-assets/guidebook/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -SHELL := /bin/bash - -# `make serve` to serve the mkdocs site on localhost. -.PHONY: serve -serve: - mkdocs serve - -# `make build` to build the static documentation site. -.PHONY: build -build: - mkdocs build - -# `make clean` cleans everything up. -.PHONY: clean -clean: - rm -rf site diff --git a/dev-assets/guidebook/build.py b/dev-assets/guidebook/build.py deleted file mode 100644 index d3789fd..0000000 --- a/dev-assets/guidebook/build.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 - -import codecs -import glob -import os -import markdown -import jinja2 -import re - -def main(): - if not os.path.isdir("./compiled"): - print("Make output directory: ./compiled") - os.mkdir("./compiled") - os.mkdir("./compiled/pages") - - # Render the main index.html template. - with codecs.open("./pages/index.html", "r", "utf-8") as fh: - html = fh.read() - html = render_template(html) - with open("./compiled/index.html", "w") as outfh: - outfh.write(html) - - # Load the Markdown wrapper HTML template. - html_wrapper = "$CONTENT" - with codecs.open("./pages/markdown.html", "r", "utf-8") as fh: - html_wrapper = fh.read() - - for md in glob.glob("./pages/*.md"): - filename = md.split(os.path.sep)[-1] - htmlname = filename.replace(".md", ".html") - print("Compile Markdown: {} -> {}".format(filename, htmlname)) - - with codecs.open(md, 'r', 'utf-8') as fh: - data = fh.read() - rendered = markdown.markdown(data, - extensions=["codehilite", "fenced_code"], - ) - html = html_wrapper.replace("$CONTENT", rendered) - html = render_template(html, - title=title_from_markdown(data), - ) - - with open(os.path.join("compiled", "pages", htmlname), "w") as outfh: - outfh.write(html) - -jinja_env = jinja2.Environment() - -def render_template(input, *args, **kwargs): - templ = jinja_env.from_string(input) - return templ.render( - app_name="Project: Doodle", - app_version=get_app_version(), - *args, **kwargs - ) - -def title_from_markdown(text): - """Retrieve the title from the first Markdown header.""" - for line in text.split("\n"): - if line.startswith("# "): - return line[2:] - -def get_app_version(): - """Get the app version from pkg/branding/branding.go in Doodle""" - ver = re.compile(r'Version\s*=\s*"(.+?)"') - with codecs.open("../../pkg/branding/branding.go", "r", "utf-8") as fh: - text = fh.read() - for line in text.split("\n"): - m = ver.search(line) - if m: - return m[1] - -if __name__ == "__main__": - main() diff --git a/dev-assets/guidebook/build.sh b/dev-assets/guidebook/build.sh deleted file mode 100755 index 11d620b..0000000 --- a/dev-assets/guidebook/build.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -if [[ ! -d "./venv" ]]; then - echo Creating Python virtualenv... - python3 -m venv ./venv - source ./venv/bin/activate - pip install -r requirements.txt -else - source ./venv/bin/activate -fi - -python build.py - -# Copy static files in. -mkdir -p compiled/pages/res -cp -r pages/res/*.* compiled/pages/res/ diff --git a/dev-assets/guidebook/docs/about.md b/dev-assets/guidebook/docs/about.md deleted file mode 100644 index e501178..0000000 --- a/dev-assets/guidebook/docs/about.md +++ /dev/null @@ -1,3 +0,0 @@ -# About Project: Doodle - -Lorem ipsum. diff --git a/dev-assets/guidebook/docs/custom-doodads/edit-external.md b/dev-assets/guidebook/docs/custom-doodads/edit-external.md deleted file mode 100644 index 3e253ff..0000000 --- a/dev-assets/guidebook/docs/custom-doodads/edit-external.md +++ /dev/null @@ -1,20 +0,0 @@ -# Drawing Doodads in an External Program - -Doodad sprites can be drawn using any image editor and saved as .png files -(with transparency). You can then create a doodad file from your series of -PNG images. - -Most of the built-in doodads that ship with the game were created in this way. - -## Create a Doodad from Images - -Save each frame of your doodad as a separate PNG image and then use the `doodad` -command-line tool to convert them to a `.doodad` file. - -```bash -# Usage: -doodad convert [options] - -# Example: -doodad convert door-closed.png door-open.png door.doodad -``` diff --git a/dev-assets/guidebook/docs/custom-doodads/edit-in-game.md b/dev-assets/guidebook/docs/custom-doodads/edit-in-game.md deleted file mode 100644 index f26901e..0000000 --- a/dev-assets/guidebook/docs/custom-doodads/edit-in-game.md +++ /dev/null @@ -1,27 +0,0 @@ -# Drawing a Doodad In-Game - -Project: Doodle has some **limited** support to draw your doodad sprites -in-game. Currently you can only draw one frame (image) for the doodad -and save it to disk. - -To start a new doodad, open the game and enter the level editor. - -Select the "New Doodad" button at the top of the screen to start drawing a -new doodad. Choose the size (square) of its sprite when prompted. - -Doodads saved in-game go in your user config directory for the game. On Linux, -this is at ~/.config/doodle. - -If you want to create a doodad with multiple frames (to animate it or have -varying states that change the doodad's appearance in the level), the -`doodad` tool is recommended. See -[drawing images in an external program](edit-external.md). - -## Future Planned Features - -Creating doodads in-game is intended to be a fully supported feature. The -following features are planned to be supported: - -* Support editing multiple frames instead of only the first frame. -* Implement some features only available on the `doodad` tool using in-game - UI, such as attaching JavaScripts to the doodad. diff --git a/dev-assets/guidebook/docs/custom-doodads/index.md b/dev-assets/guidebook/docs/custom-doodads/index.md deleted file mode 100644 index 67fa6fc..0000000 --- a/dev-assets/guidebook/docs/custom-doodads/index.md +++ /dev/null @@ -1,43 +0,0 @@ -# Creating Custom Doodads - -Project: Doodle is designed to be modder friendly and provides tools to help -you create your own custom doodads to use in your levels. - -You can draw the sprites for the doodad either in-game or using an external -image editor. Then, you can program their logic using JavaScript to make them -"do" stuff in-game and interact with the player and other doodads. - -* Drawing your Doodad's Sprites - * [In-Game](edit-in-game.md) - * [In an External Program](edit-external.md) -* Program its Behavior - * [JavaScript](scripts.md) - -## doodad (Command Line Tool) - -Your copy of the game should have shipped with a `doodad` command-line tool -bundled with it. On Windows it's called `doodad.exe` and should be in the same -folder as the game executable. On Mac OS, it is inside the .app bundle. - -The `doodad` tool provides a command-line interface to create and inspect -doodad and level files from the game. You'll need to use this tool, at the very -least, to attach a JavaScript to your doodad to make it "do" stuff in-game. - -You can create a doodad from PNG images on disk, attach or view the JavaScript -source on them, and view/edit metadata. - -```bash -# (the $ represents the shell prompt in a command-line terminal) - -# See metadata about a doodad file. -$ doodad show /path/to/custom.doodad - -# Create a new doodad based on PNG images on disk. -$ doodad convert frame0.png frame1.png frame2.png output.doodad - -# Add and view a custom script attached to the doodad. -$ doodad install-script index.js custom.doodad -$ doodad show --script custom.doodad -``` - -More info on the [`doodad` tool](../doodad-tool.md) here. diff --git a/dev-assets/guidebook/docs/custom-doodads/scripts.md b/dev-assets/guidebook/docs/custom-doodads/scripts.md deleted file mode 100644 index 7f9a2d8..0000000 --- a/dev-assets/guidebook/docs/custom-doodads/scripts.md +++ /dev/null @@ -1,564 +0,0 @@ -# Doodad Scripts - -Doodads are programmed using JavaScript which gives them their behavior -and ability to interact with the player and other doodads. - -Doodad scripts are run during "Play Mode" when a level _containing_ the doodad -is being played. You can install a JavaScript (.js) file into a doodad using -the command-line `doodad` program. - -An example Doodad script looks like the following: - -```javascript -// main() is called on level initialization for each -// instance ("actor") of the doodad. -function main() { - // Logs go to the game's log file (standard output on Linux/Mac). - console.log("%s initialized!", Self.Title); - - // If our doodad has 'solid' parts that should prohibit movement, - // define the hitbox here. Coordinates are relative so 0,0 is the - // top-left pixel of the doodad's sprite. - Self.SetHitbox(0, 0, 64, 12); - - // Handle a collision when another doodad (or player) has entered - // the space of our doodad. - Events.OnCollide(function(e) { - // The `e` object holds information about the event. - console.log("Actor %s has entered our hitbox!", e.Actor.ID()); - - // InHitbox is `true` if we defined a hitbox for ourselves, and - // the colliding actor is inside of the hitbox we defined. - if (e.InHitbox) { - // To prohibit movement, return false from the OnCollide handler. - // If you don't return false, the actor is allowed to keep on - // moving through. - return false; - } - - // When movement is finalized, OnCollide is called one final time - // with e.Settled=true; it is only then that a doodad should run - // event handlers for a logical collide event. - if (e.Settled) { - // do something - Message.Publish("power", true); - } - }); - - // OnLeave is called when an actor, who was previously colliding with - // us, is no longer doing so. - Events.OnLeave(function(e) { - console.log("Actor %s has stopped colliding!", e.Actor.ID()); - }) -} -``` - -# Installing a Doodad Script - -Use the command-line `doodad` tool to attach a script to your doodad file: - -```bash -# Attach the JavaScript at "script.js" to the doodad file "filename.doodad" -doodad install-script script.js filename.doodad - -# To view the script currently attached to a doodad -# (prints the script to your terminal) -doodad show --script filename.doodad -``` - -# Testing Your Script - -The best way to test your doodad script is to use it in a level! - -Run the game in a console to watch the log output, and you can use functions -like `console.log()` in your script to help debug issues. Drag your custom -doodad into a level and playtest it! Your script's main() function is called -when the level instance of your doodad is initialized. - -# JavaScript API - -The following global variables are available to all Doodad scripts. - -## Self - -Self holds data about the current doodad instance loaded inside of a level. - -**String attributes:** - -* Self.Title: the doodad title. -* Self.Filename: the doodad filename (useful for inventory items). - -Methods are below. - -### Self.ID() string - -Returns the "actor ID" of the doodad instance loaded inside of a level. This -is usually a random UUID string that was saved with the level data. - -### Self.GetTag(string name) string - -Return a "tag" that was saved with the doodad's file data. - -Tags are an arbitrary key/value data store attached to the doodad file. -You can use the `doodad.exe` tool shipped with the game to view and manage tags -on your own custom doodads: - -```bash -# Command-line doodad tool usage: - -# Show information about a doodad, look for the "Tags:" section. -doodad show filename.doodad - -# Set a tag. "-t" for short. -doodad edit-doodad --tag 'color=blue' filename.doodad - -# Set the tag to empty to remove it. -doodad edit-doodad -t 'color=' filename.doodad -``` - -This is useful for a set of multiple doodads to share the same script but -have different behavior depending on how each is tagged. - -### Self.Position() Point - -Returns the doodad's current position in the level. - -Point is an object with .X and .Y integer values. - -```javascript -var p = Self.Position() -console.log("I am at %d,%d", p.X, p.Y) -``` - -### Self.SetHitbox(x, y, w, h int) - -Configure the "solid hitbox" of this doodad. - -The X and Y coordinates are relative to the doodad's sprite: (0,0) is the top -left pixel of the doodad. The W and H are the width and height of the hitbox -starting at those coordinates. - -When another doodad enters the area of your doodad's sprite (for example, the -player character has entered the square shape of your doodad sprite) your script -begins to receive OnCollide events from the approaching actor. - -The OnCollide event tells you if the invading doodad is inside your custom -hitbox which you define here (`InHitbox`) making it easy to make choices based -on that status. - -Here's an example script for a hypothetical "locked door" doodad that acts -solid but only on a thin rectangle in the middle of its sprite: - -```javascript -// Example script for a "locked door" -function main() { - // Suppose the doodad's sprite size is 64x64 pixels square. - // The door is in side profile where the door itself ranges from pixels - // (20, 0) to (24, 64) - Self.SetHitbox(20, 0, 24, 64) - - // OnCollide handlers. - Events.OnCollide(function(e) { - // The convenient e.InHitbox tells you if the colliding actor is - // inside the hitbox we defined. - if (e.InHitbox) { - // Return false to protest the collision (act solid). - return false; - } - }); -} -``` - -### Self.SetVelocity(Velocity) - -Set the doodad's velocity. Velocity is a type that can be created with the -Velocity() constructor, which takes an X and Y value: - -```javascript -Self.SetVelocity( Velocity(3.2, 7.0) ); -``` - -A positive X velocity propels the doodad to the right. A positive Y velocity -propels the doodad downward. - -### Self.SetMobile(bool) - -Call `SetMobile(true)` if the doodad will move on its own. - -This is for mobile doodads such as the player character and enemy mobs. -Stationary doodads like buttons, doors, and trapdoors do not mark themselves -as mobile. - -Mobile doodads incur extra work for the game doing collision checking so only -set this to `true` if your doodad will move (i.e. changes its Velocity or -Position). - -```javascript -Self.SetMobile(true); -``` - -### Self.SetGravity(bool) - -Set whether gravity applies to this doodad. By default doodads are stationary -and do not fall downwards. The player character and some mobile enemies that -want to be affected by gravity should opt in to this. - -```javascript -Self.SetGravity(true); -``` - -### Self.ShowLayer(index int) - -Switch the active layer of the doodad to the layer at this index. - -A doodad file can contain multiple layers, or images. The first and default -layer is at index zero, the second layer at index 1, and so on. - -```javascript -Self.ShowLayer(0); // 0 is the first and default layer -Self.ShowLayer(1); // show the second layer instead -``` - -### Self.ShowLayerNamed(name string) - -Switch the active layer by name instead of index. - -Each layer has an arbitrary name that it can be addressed by instead of needing -to keep track of the layer index. - -Doodads created by the command-line `doodad` tool will have their layers named -automatically by their file name. The layer **indexes** will retain the same -order of file names passed in, with 0 being the first file: - -```bash -# Doodad tool-created doodads have layers named after their file names. -# example "open-1.png" will be named "open-1" -doodad convert door.png open-1.png open-2.png open-3.png my-door.doodad -``` - -### Self.AddAnimation(name string, interval int, layers list) - -Register a named animation for your doodad. `interval` is the time in -milliseconds before going to the next frame. `layers` is an array of layer -names or indexes to be used for the animation. - -Doodads can animate by having multiple frames (images) in the same file. -Layers are ordered (layer 0 is the first, then increments from there) and -each has a name. This function can take either identifier to specify -which layers are part of the animation. - -```javascript -// Animation named "open" using named layers, 100ms delay between frames. -Self.AddAnimation("open", 100, ["open-1", "open-2", "open-3"]); - -// Animation named "close" using layers by index. -Self.AddAnimation("close", 100, [3, 2, 1]); -``` - -### Self.PlayAnimation(name string, callback func()) - -This starts playing the named animation. The callback function will be called -when the animation has completed. - -```javascript -Self.PlayAnimation("open", function() { - console.log("I've finished opening!"); - - // The callback is optional; use null if you don't need it. - Self.PlayAnimation("close", null); -}); -``` - -### Self.IsAnimating() bool - -Returns true if an animation is currently being played. - -### Self.StopAnimation() - -Stops any currently playing animation. - - -* Self.Doodad(): a pointer to the doodad's file data. - * Self.Doodad().Title: get the title of the doodad file. - * Self.Doodad().Author: the name of the author who wrote the doodad. - * Self.Doodad().Script: the doodad's JavaScript source code. Note that - modifying this won't have any effect in-game, as the script had already - been loaded into the interpreter. - * Self.Doodad().GameVersion: the version of {{ app_name }} that was used - when the doodad was created. - -### Self.Destroy() - -This destroys the current instance of the doodad as it appears in a level. - -For example, a Key destroys itself when it's picked up so that it disappears -from the level and can't be picked up again. Call this function when the -doodad instance should be destroyed and removed from the active level. - ------ - -## Console Logging - -Like in node.js and the web browser, `console.log` and friends are available -for logging from a doodad script. Logs are emitted to the same place as the -game's logs are. - -```javascript -console.log("Hello world!"); -console.log("Interpolate strings '%s' and numbers '%d'", "string", 123); -console.debug("Debug messages shown when the game is in debug mode"); -console.warn("Warning-level messages"); -console.error("Error-level messages"); -``` - ------ - -## Timers and Intervals - -Like in a web browser, functions such as setTimeout and setInterval are -supported in doodad scripts. - -### setTimeout(function, milliseconds int) int - -setTimeout calls your function after the specified number of milliseconds. - -1000ms are in one second. - -Returns an integer "timeout ID" that you'll need if you want to cancel the -timeout with clearTimeout. - -### setInterval(function, milliseconds int) int - -setInterval calls your function repeatedly after every specified number of -milliseconds. - -Returns an integer "interval ID" that you'll need if you want to cancel the -interval with clearInterval. - -### clearTimeout(id int) - -Cancels the timeout with the given ID. - -### clearInterval(id int) - -Cancels the interval with the given ID. - ------ - -## Type Constructors - -Some methods may need data of certain native types that aren't available in -JavaScript. These global functions will initialize data of the correct types: - -### RGBA(red, green, blue, alpha uint8) - -Creates a Color type from red, green, blue and alpha values (integers between -0 and 255). - -### Point(x, y int) - -Creates a Point object with X and Y coordinates. - -### Vector(x, y float64) - -Creates a Vector object with X and Y dimensions. - ------ - -## Global Functions - -Some useful globally available functions: - -### EndLevel() - -This ends the current level, i.e. to be used by the goal flag. - -### Flash(message string, args...) - -Flash a message on screen to the user. - -Flashed messages appear at the bottom of the screen and fade out after a few -moments. If multiple messages are flashed at the same time, they stack from the -bottom of the window with the newest message on bottom. - -Don't abuse this feature as spamming it may annoy the player. - -### GetTick() uint64 - -Returns the current game tick. This value started at zero when the game was -launched and increments every frame while running. - -### time.Now() time.Time - -This exposes the Go standard library function `time.Now()` that returns the -current date and time as a Go time.Time value. - -### time.Add(t time.Time, milliseconds int64) time.Time - -Add a number of milliseconds to a Go Time value. - --------- - -## Event Handlers - -Doodad scripts can respond to certain events using functions on the global -`Events` variable. - -### Events.OnCollide( func(event) ) - -OnCollide is called when another actor is colliding with your doodad's sprite -box. The function is given a CollideEvent object which has the following -attributes: - -* Actor: the doodad which is colliding with your doodad. -* Overlap (Rect): a rectangle of where the two doodads' boxes are overlapping, - relative to your doodad sprite's box. That is, if the Actor was moving in from - the left side of your doodad, the X value would be zero and W would be the - number of pixels of overlap. -* InHitbox (bool): true if the colliding actor's hitbox is intersecting with - the hitbox you defined with SetHitbox(). -* Settled (bool): This is `false` when the game is trying to move the colliding - doodad and is sussing out whether or not your doodad will act solid and - protest its movement. When the game has settled the location of the colliding - doodad it will call OnCollide a final time with Settled=true. If your doodad - has special behavior when touched (i.e. a button that presses in), you should - wait until Settled=true before running your handler for that. - -### Events.OnLeave( func(event) ) - -Called when an actor that _was_ colliding with your doodad is no longer -colliding (or has left your doodad's sprite box). - -### Events.RunKeypress( func(event) ) - -Handle a keypress. `event` is an `event.State` from the render engine. - -TODO: document that. - ------ - -## Pub/Sub Communication - -Doodads in a level are able to send and receive messages to other doodads, -either those that they are **linked** to or those that listen on a more -'broadcast' frequency. - -> **Linking** is when the level author connected two doodads together with -> the Link Tool. The two doodads' scripts can communicate with each other -> in-game over that link. - -For example, if the level author links a Button to an Electric Door, the button -can send a "power" event to the door so that it can open when a player touches -the button. - -Doodads communicate in a "publisher/subscriber" model: one doodad publishes an -event with a name and data, and other doodads subscribe to the named event to -receive that data. - -### Official, Standard Pub/Sub Messages - -The following message names and data types are used by the game's default -doodads. You're free to use these in your own custom doodads. - -If extending this list with your own custom events, be careful to choose a -unique namespace to prevent collision with other users' custom doodads and -their custom event names. - -| Name | Data Type | Description | -|------|-----------|--------------| -| power | boolean | Communicates a "powered" (true) or "not powered" state, as in a Button to an Electric Door. | -| broadcast:state-change | boolean | An "ON/OFF" button was hit and all state blocks should flip. | - -### Message.Publish(name string, data...) - -Publish a named message to all of your **linked** doodads. - -`data` is a list of arbitrary arguments to send with the message. - -```javascript -// Example button doodad that emits a "power" (bool) state to linked doodads -// that subscribe to this event. -function main() { - // When an actor collides with the button, emit a powered state. - Events.OnCollide(function(e) { - Message.Publish("power", true); - }); - - // When the actor leaves the button, turn off the power. - Events.OnLeave(function(e) { - Message.Publish("power", false); - }) -} -``` - -### Message.Subscribe(name string, function) - -Subscribe to a named message from any **linked** doodads. - -The function receives the data that was passed with the message. Its data type -is arbitrary and will depend on the type of message. - -```javascript -// Example electronic device doodad that responds to power from linked buttons. -function main() { - // Boolean to store if our electric device has juice. - var powered = false; - - // Do something while powered - setInterval(function() { - if (powered) { - console.log("Brmm...") - } - }, 1000); - - // Subscribe to the `power` event by a linked button or other power source. - Message.Subscribe("power", function(boolValue) { - console.log("Powered %s!", boolValue === true ? "on" : "off"); - powered = boolValue; - }); -} -``` - -### Message.Broadcast(name string, data...) - -This publishes a named message to **every** doodad in the level, whether it -was linked to the broadcaster or not. - -For example the "ON/OFF" button globally toggles a boolean state in every -state block that subscribes to the `broadcast:state-change` event. - -If you were to broadcast an event like `power` it would activate every single -power-sensitive doodad on the level. - -```javascript -// Example two-state block that globally receives the state-change broadcast. -function main() { - var myState = false; - Message.Subscribe("broadcast:state-change", function(boolValue) { - // Most two-state blocks just flip their own state, ignoring the - // boolValue passed with this message. - myState = !myState; - }); -} - -// Example ON/OFF block that emits the state-change broadcast. It also -// subscribes to the event to keep its own state in sync with all the other -// ON/OFF blocks on the level when they get hit. -function main() { - var myState = false; - - // Listen for other ON/OFF button activations to keep our state in - // sync with theirs. - Message.Subscribe("broadcast:state-change", function(boolValue) { - myState = boolValue; - }); - - // When collided with, broadcast the state toggle to all state blocks. - Events.OnCollide(function(e) { - if (e.Settled) { - myState = !!myState; - Message.Broadcast("broadcast:state-change", myState); - } - }) -} -``` diff --git a/dev-assets/guidebook/docs/custom-levels/index.md b/dev-assets/guidebook/docs/custom-levels/index.md deleted file mode 100644 index cd9369e..0000000 --- a/dev-assets/guidebook/docs/custom-levels/index.md +++ /dev/null @@ -1,99 +0,0 @@ -# Creating Custom Levels - -One of the core gameplay features is its Level Editor which lets you draw your -own custom maps to play and share with others. - -From the game's Main Menu, click on the "Create a Level" button to open the -level editor. To edit an existing custom level, click on the "Edit a Level" -button instead. - -## Level Properties - -When creating a new level, you first choose some settings for it. These are -described below: - -### Page Type - -This setting controls the size and boundaries of your level, and control the -appearance of the notebook paper background of your level. - -* **Bounded** is the default. The camera won't scroll past the top-left corner - of the page (0,0), and the level size is capped to 2550x3300, or the - approximate size of an 11:9 standard sheet of notebook paper in pixels. -* **No Negative Space** is like Bounded, but the width and height of the level - have no boundary. Levels can grow "infinitely" to the right and downward - but no negative coordinates past the top or left edge. -* **Unbounded** allows for "infinite" sized maps that give unlimited room to - grow your level. The wallpaper on this level type only uses the "tiling" - pattern, so notebook-themed levels won't show the top/left decorations. - -### Wallpaper - -The wallpaper affects the "theme" of your level. Project: Doodle is themed around -hand-drawn mazes on paper, so the built-in themes look like various kinds of -paper. - -* **Notebook** looks like standard ruled notebook paper. It's a white paper with - blue horizontal lines, a single red vertical line down the left, and a wide - margin on the top and left edges. -* **Legal Pad** looks like ruled yellow legal pad. It's similar to Notebook but - has yellow paper and a second vertical red line down the left. -* **Blueprint** is a dark blueprint paper background with a repeating grid pattern. - Notably, the default Color Palette for this theme is different than normal: - "solid" lines are white instead of black, to show up better against the dark - background. - -The decorations of the wallpaper vary based on the Page Type. For example, the -Notebook and Legal Pad have extra padding on the top of the page and red lines -going down just the left side, and the rest of the level uses the repeating blue -lines pattern. The page types and their effect on the wallpapers are: - -* **Bounded** and **No Negative Space** will show the decorations for the top - and left edges of the page, as these levels are bounded on their top/left - corner. -* **Unbounded** levels only use the repeating tiled pattern across the entire - level, because there is no top-left boundary to anchor those decorations to. - -## Editor Mode Interface - -![Level Editor View](../images/editor-1.png) - -Quick 5-minute tour of what you're looking at: - -* The top of the window has your **Menu Bar**: - * **New Level** opens the "Create a New Level" menu. - * **New Doodad** opens the Doodad Editor for drawing a new custom doodad. - You're prompted for the size of the doodad, which will be its width and - height boundary. For example, a size of "100" means a 100x100 pixel graphic - for your custom doodad. - * **Save** and **Save as...** let you save the current Level or Doodad you're - drawing to disk. "Save" will only ask for the filename once whereas "Save as" - asks every time. - * **Load** opens the "Edit a Level" menu to choose a Level or Doodad to edit. - * **Options** options the Level Options dialog so you can modify the page type - and wallpaper setting. -* The panel on the left side of the window is your **Tool Box**. Clicking these - buttons activates a specific drawing tool or mode: - * **Pencil Tool** lets you click, drag, and draw pixels of your selected - Palette color onto your level freehand. - * **Line Tool** lets you easily draw a straight line between two points. Click - in your level where you want the first point to be, and drag your mouse to - the second point. Release the mouse to commit the line to your drawing. - * **Rectangle Tool** lets you easily draw rectangles on your level. - * **Ellipse Tool** lets you draw circles or elliptical shapes. - * **Doodad Tool** lets you drag doodads such as buttons and doors onto your - level. See the [Doodad Tool](#doodad-tool) below. - * **Link Tool** lets you link doodads together so that they can interact off - each other. For example, a Button connected to an Electric Door will cause - the door to open and close when the button is pressed. See [Link Tool](#link-tool) - below. - * **Eraser Tool** cleans up your mistakes. Click and drag over pixels you've - drawn to delete the pixels from your level. - * **Brush Size:** the "Size:" label shows the brush size of your current drawing - tool. This translates to the line thickness, or how big your pixels are when - drawn into the level. Click the + and - buttons to increase or decrease the - brush size, and draw thicker or thinner lines. -* The panel on the right side of the window is your **Palette** of colors to - draw with. - -![Doodad Toolbar View](../images/editor-2.png) diff --git a/dev-assets/guidebook/docs/doodad-tool.md b/dev-assets/guidebook/docs/doodad-tool.md deleted file mode 100644 index 02c3ef0..0000000 --- a/dev-assets/guidebook/docs/doodad-tool.md +++ /dev/null @@ -1,118 +0,0 @@ -# Doodad Tool - -The game ships with a command-line program called `doodad` which assists in -creating and managing custom doodads and levels. - -The `doodad` tool can show and set details on .doodad and .level files used by -the game, create new doodads from PNG images and attach custom JavaScript source -to program behavior of doodads. - -## Where to Find It - -The `doodad` tool should be in the same place as the game executable. - -On Windows, the program is called `doodad.exe` and comes in the zip file next -to the game executable, `doodle.exe`. - -On Linux, it will typically be at `/opt/project-doodle/doodad`. - -On Mac OS, it is found inside the .app bundle. - -## Usage - -Run `doodad --help` to get usage information. - -The program includes several sub-commands, such as `doodad convert`. Type a -subcommand and `--help` to get help on that command, for example: - -```bash -doodad convert --help -``` - -# Examples - -Here are some common scenarios and use cases for the doodad tool. - -## Show - -```bash -# Usage: -doodad show [doodad or level filename] -``` - -Shows metadata and details about a level or doodad file. - -Examples: - -```bash -$ doodad show button.doodad -===== Doodad: button.doodad ===== -Headers: - File version: 1 - Game version: 0.0.10-alpha - Doodad title: Button - Author: Noah - Locked: true - Hidden: false - Script size: 473 bytes - -Palette: - - Swatch name: Color<#000000+ff> - Attributes: solid - Color: #000000 - - Swatch name: Color<#666666+ff> - Attributes: none - Color: #666666 - - Swatch name: Color<#999999+ff> - Attributes: fire - Color: #999999 - -Layer 0: button1 -Chunks: - Pixels Per Chunk: 37^2 - Number Generated: 1 - Coordinate Range: (0,0) ... (36,36) - World Dimensions: 36x36 - Use -chunks or -verbose to serialize Chunks - -Layer 1: button2 -Chunks: - Pixels Per Chunk: 37^2 - Number Generated: 1 - Coordinate Range: (0,0) ... (36,36) - World Dimensions: 36x36 - Use -chunks or -verbose to serialize Chunks -``` - -## Convert - -```bash -# Usage: -doodad convert [options] -``` - -### Creating a Doodad from PNG images - -Suppose you have PNG images named "frame0.png" through "frame3.png" and want -to create a doodad from those images. This will convert them to the doodad -file "custom.doodad": - -```bash -# Convert PNG images into a doodad. -doodad convert frame0.png frame1.png frame2.png frame3.png custom.doodad - -# The same, but also attach custom tags with the doodad. -doodad convert --tag color=blue frame{0,1,2,3}.png custom.doodad -``` - -### Convert a level to a PNG image - -```bash -doodad convert my.level output.png -``` - -### Create a level from a PNG image - -```bash -doodad convert level.png output.level -``` diff --git a/dev-assets/guidebook/docs/images/editor-1.png b/dev-assets/guidebook/docs/images/editor-1.png deleted file mode 100644 index ff354b8..0000000 Binary files a/dev-assets/guidebook/docs/images/editor-1.png and /dev/null differ diff --git a/dev-assets/guidebook/docs/images/editor-2.png b/dev-assets/guidebook/docs/images/editor-2.png deleted file mode 100644 index 1c48074..0000000 Binary files a/dev-assets/guidebook/docs/images/editor-2.png and /dev/null differ diff --git a/dev-assets/guidebook/docs/images/main-menu.png b/dev-assets/guidebook/docs/images/main-menu.png deleted file mode 100644 index ddd7db1..0000000 Binary files a/dev-assets/guidebook/docs/images/main-menu.png and /dev/null differ diff --git a/dev-assets/guidebook/docs/index.md b/dev-assets/guidebook/docs/index.md deleted file mode 100644 index a09f86a..0000000 --- a/dev-assets/guidebook/docs/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# Welcome to Project: Doodle - -![](images/main-menu.png) - -[Project: Doodle](about.md) is a drawing-based maze game themed around hand-drawn -maps on paper. You can draw a level for a 2D platformer game, drag-and-drop -"doodads" such as buttons and doors into your level, and play it. - -## Table of Contents - -* [Creating Custom Levels](custom-levels/) -* [Creating Custom Doodads](custom-doodads/) - * [Draw Sprites In-Game](custom-doodads/edit-in-game.md) - * [Draw Sprites with an External Program](custom-doodads/edit-external.md) - * [Program Them with JavaScript](custom-doodads/scripts.md) diff --git a/dev-assets/guidebook/mkdocs.yml b/dev-assets/guidebook/mkdocs.yml deleted file mode 100644 index b6b75f3..0000000 --- a/dev-assets/guidebook/mkdocs.yml +++ /dev/null @@ -1,8 +0,0 @@ -site_name: "Project: Doodle Guidebook" -nav: - - Home: index.md - - About: about.md - - "Custom Doodads": custom-doodads/index.md -markdown_extensions: - - toc: - permalink: "#" diff --git a/dev-assets/guidebook/requirements.txt b/dev-assets/guidebook/requirements.txt deleted file mode 100644 index f27036f..0000000 --- a/dev-assets/guidebook/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -markdown -jinja2 diff --git a/go.mod b/go.mod index 96cf3ab..f2b845d 100644 --- a/go.mod +++ b/go.mod @@ -11,12 +11,18 @@ require ( git.kirsle.net/go/render v0.0.0-20200710023247-e5f4c3a16860 git.kirsle.net/go/ui v0.0.0-20200710023146-e2a561fbd04c github.com/alecthomas/gocyclo v0.0.0-20150208221726-aa8f8b160214 // indirect + github.com/alexkohler/nakedret v1.0.0 // indirect + github.com/client9/misspell v0.3.4 // indirect github.com/google/uuid v1.1.2 github.com/gordonklaus/ineffassign v0.0.0-20201107091007-3b93a8888063 // indirect github.com/jgautheron/goconst v0.0.0-20201108215931-f8e4fe8351cd // indirect github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f + github.com/kisielk/errcheck v1.4.0 // indirect github.com/mdempsky/maligned v0.0.0-20201101000000-d73c43cb16d0 // indirect + github.com/mdempsky/unconvert v0.0.0-20200228143138-95ecdbfc0b5f // indirect + github.com/opennota/check v0.0.0-20180911053232-0c771f5545ff // indirect github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac + github.com/stripe/safesql v0.2.0 // indirect github.com/tomnomnom/xtermcolor v0.0.0-20160428124646-b78803f00a7e // indirect github.com/urfave/cli v1.22.5 github.com/urfave/cli/v2 v2.3.0 @@ -27,6 +33,7 @@ require ( golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 google.golang.org/appengine v1.6.7 // indirect gopkg.in/sourcemap.v1 v1.0.5 // indirect + honnef.co/go/tools v0.0.1-2020.1.6 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 // indirect diff --git a/go.sum b/go.sum index 636d3c9..1a7e73a 100644 --- a/go.sum +++ b/go.sum @@ -13,15 +13,21 @@ git.kirsle.net/go/render v0.0.0-20200710023247-e5f4c3a16860 h1:0jaJRNlBb/OCB/QSk git.kirsle.net/go/render v0.0.0-20200710023247-e5f4c3a16860/go.mod h1:ss7pvZbGWrMaDuZwyUTjV9+T0AJwAkxZZHwMFsvHrkk= git.kirsle.net/go/ui v0.0.0-20200710023146-e2a561fbd04c h1:8fvCXsFGK91WtiTIAdklAN3gHVNYD0hvFvWfznCLMGc= git.kirsle.net/go/ui v0.0.0-20200710023146-e2a561fbd04c/go.mod h1:Q93RpHNXvbGr3dQ9mmcEN8ZC3dtNQ4FwivSx53tKOVA= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/alecthomas/gocyclo v0.0.0-20150208221726-aa8f8b160214 h1:YI/8G3uLbYyowJeOPVL6BMKe2wbL54h0FdEKmncU6lU= github.com/alecthomas/gocyclo v0.0.0-20150208221726-aa8f8b160214/go.mod h1:Ef5UOtJdJ5rVFObdOVsrNgKV/Wf4I+daTCSk8GTrHIk= github.com/alexflint/go-arg v0.0.0-20160306200701-e71d6514f40a h1:Bc+P30eTWphhueyACA/fjiHJXRDq/kGiqO38nGxvml0= github.com/alexflint/go-arg v0.0.0-20160306200701-e71d6514f40a/go.mod h1:PHxo6ZWOLVMZZgWSAqBynb/KhIqoGO6WKwOVX7rM9dg= +github.com/alexkohler/nakedret v1.0.0 h1:S/bzOFhZHYUJp6qPmdXdFHS5nlWGFmLmoc8QOydvotE= +github.com/alexkohler/nakedret v1.0.0/go.mod h1:tfDQbtPt67HhBK/6P0yNktIX7peCxfOp0jO9007DrLE= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gordonklaus/ineffassign v0.0.0-20201107091007-3b93a8888063 h1:dKprcOvlsvqfWn/iGvz+oYuC2axESeSMuF8dDrWMNsE= @@ -30,6 +36,8 @@ github.com/jgautheron/goconst v0.0.0-20201108215931-f8e4fe8351cd h1:xfrCuNSOStub github.com/jgautheron/goconst v0.0.0-20201108215931-f8e4fe8351cd/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f h1:dKccXx7xA56UNqOcFIbuqFjAWPVtP688j5QMgmo6OHU= github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f/go.mod h1:4rEELDSfUAlBSyUjPG0JnaNGjf13JySHFeRdD/3dLP0= +github.com/kisielk/errcheck v1.4.0 h1:ueN6QYA+c7eDQo7ebpNdYR8mUJZThiGz9PEoJEMGPzA= +github.com/kisielk/errcheck v1.4.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -37,14 +45,21 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mdempsky/maligned v0.0.0-20201101000000-d73c43cb16d0 h1:+6XJvFZBYbNv/nSekNWFZyaGNMXcPnZ4n/HHoCXn+Ms= github.com/mdempsky/maligned v0.0.0-20201101000000-d73c43cb16d0/go.mod h1:3UB4iTzhLciyWcrrvXSkrtCIU+IJ5GCfEmnleHRsxL4= +github.com/mdempsky/unconvert v0.0.0-20200228143138-95ecdbfc0b5f h1:Kc3s6QFyh9DLgInXpWKuG+8I7R7lXbnP7mcoOVIt6KY= +github.com/mdempsky/unconvert v0.0.0-20200228143138-95ecdbfc0b5f/go.mod h1:AmCV4WB3cDMZqgPk+OUQKumliiQS4ZYsBt3AXekyuAU= +github.com/opennota/check v0.0.0-20180911053232-0c771f5545ff h1:lRHufowVGvUvxGsPveAZOpSa/9T5Gpxg6d7UbHCA9MQ= +github.com/opennota/check v0.0.0-20180911053232-0c771f5545ff/go.mod h1:tydB+MZxWpY8M/NRu7jQhND/mXuLAPsKcSV6JkzofsA= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac h1:kYPjbEN6YPYWWHI6ky1J813KzIq/8+Wg4TO4xU7A/KU= github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/stripe/safesql v0.2.0 h1:xiefmCDd8c35PVSGrL2FhBiaKxviXnGziBDOpOejeBE= +github.com/stripe/safesql v0.2.0/go.mod h1:q7b2n0JmzM1mVGfcYpanfVb2j23cXZeWFxcILPn3JV4= github.com/tomnomnom/xtermcolor v0.0.0-20160428124646-b78803f00a7e h1:Ee+VZw13r9NTOMnwTPs6O5KZ0MJU54hsxu9FpZ4pQ10= github.com/tomnomnom/xtermcolor v0.0.0-20160428124646-b78803f00a7e/go.mod h1:fSIW/szJHsRts/4U8wlMPhs+YqJC+7NYR+Qqb1uJVpA= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= @@ -68,6 +83,7 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= @@ -91,11 +107,15 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200225230052-807dcd883420/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b h1:zSzQJAznWxAh9fZxiPy2FZo+ZZEYoYFYYDYdOrU7AaM= golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201030204249-4fc0492b8eca h1:KWfVIHfTHZf4IQhrLjrbG+kLyoSym7yYp0WgqtOVH9s= golang.org/x/tools v0.0.0-20201030204249-4fc0492b8eca/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -115,6 +135,8 @@ gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.1-2020.1.6 h1:W18jzjh8mfPez+AwGLxmOImucz/IFjpNlrKVnaj2YVc= +honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo=