doodle/pkg/balance/numbers.go

147 lines
4.5 KiB
Go
Raw Normal View History

package balance
import (
"time"
"git.kirsle.net/go/render"
)
Zipfiles as File Format for Levels and Doodads Especially to further optimize memory for large levels, Levels and Doodads can now read and write to a ZIP file format on disk with chunks in external files within the zip. Existing doodads and levels can still load as normal, and will be converted into ZIP files on the next save: * The Chunker.ChunkMap which used to hold ALL chunks in the main json/gz file, now becomes the cache of "hot chunks" loaded from ZIP. If there is a ZIP file, chunks not accessed recently are flushed from the ChunkMap to save on memory. * During save, the ChunkMap is flushed to ZIP along with any non-loaded chunks from a previous zipfile. So legacy levels "just work" when saving, and levels loaded FROM Zip will manage their ChunkMap hot memory more carefully. Memory savings observed on "Azulian Tag - Forest.level": * Before: 1716 MB was loaded from the old level format into RAM along with a slow load screen. * After: only 243 MB memory was used by the game and it loaded with a VERY FAST load screen. Updates to the F3 Debug Overlay: * "Chunks: 20 in 45 out 20 cached" shows the count of chunks inside the viewport (having bitmaps and textures loaded) vs. chunks outside which have their textures freed (but data kept), and the number of chunks currently hot cached in the ChunkMap. The `doodad` tool has new commands to "touch" your existing levels and doodads, to upgrade them to the new format (or you can simply open and re-save them in-game): doodad edit-level --touch ./example.level doodad edit-doodad --touch ./example.doodad The output from that and `doodad show` should say "File format: zipfile" in the headers section. To do: * File attachments should also go in as ZIP files, e.g. wallpapers
2022-04-30 03:34:59 +00:00
// Format for level and doodad files.
type Format int
const (
FormatJSON Format = iota // v0: plain json files
FormatGZip // v1: gzip compressed json files
FormatZipfile // v2: zip archive with external chunks
)
// Numbers.
var (
// Window dimensions.
Width = 1024
Height = 768
// Title screen height needed for the main menu. Phones in landscape
// mode will switch to the horizontal layout if less than this height.
TitleScreenResponsiveHeight = 600
// Speed to scroll a canvas with arrow keys in Edit Mode.
CanvasScrollSpeed = 8
FollowActorMaxScrollSpeed = 64
Implement Chunk System for Pixel Data Starts the implementation of the chunk-based pixel storage system for levels and drawings. Previously the levels had a Pixels structure which was just an array of X,Y and palette index triplets. The new chunk system divides the map up into square chunks, and lets each chunk manage its own memory layout. The "MapAccessor" layout is implemented first which is a map of X,Y coordinates to their Swatches (pointer to an index of the palette). When serialized the MapAccessor maps the "X,Y": "index" similarly to the old Pixels array. The object hierarchy for the chunk system is like: * Chunker: the manager of the chunks who keeps track of the ChunkSize and a map of "chunk coordinates" to the chunk in charge of it. * Chunk: a part of the drawing ChunkSize length square. A chunk has a Type (of how it stores its data, 0 being a map[Point]Swatch and 1 being a [][]Swatch 2D array), and the chunk has an Accessor which implements the underlying type. * Accessor: an interface for a Chunk to provide access to its pixels. * MapAccessor: a "sparse map" of coordinates to their Swatches. * GridAccessor: TBD, will be a "dense" 2D grid of Swatches. The JSON files are loaded in two passes: 1. The chunks only load their swatch indexes from disk. 2. With the palette also loaded, the chunks are "inflated" and linked to their swatch pointers. Misc changes: * The `level.Canvas` UI widget switches from the old Grid data type to being able to directly use a `level.Chunker` * The Chunker is a shared data type between the on-disk level format and the actual renderer (level.Canvas), so saving the level is easy because you can just pull the Chunker out from the canvas. * ChunkSize is stored inside the level file and the default value is at balance/numbers.go: 1000
2018-09-23 22:20:45 +00:00
// Window scrolling behavior in Play Mode.
ScrollboxOffset = render.Point{ // from center of screen
X: 60,
Y: 60,
}
// Player speeds
PlayerMaxVelocity float64 = 7
PlayerJumpVelocity float64 = -23
PlayerAcceleration float64 = 0.12
Gravity float64 = 7
GravityAcceleration float64 = 0.1
SwimGravity float64 = 3
SwimJumpVelocity float64 = -12
SwimJumpCooldown uint64 = 24 // number of frames of cooldown between swim-jumps
SlopeMaxHeight = 8 // max pixel height for player to walk up a slope
Implement Chunk System for Pixel Data Starts the implementation of the chunk-based pixel storage system for levels and drawings. Previously the levels had a Pixels structure which was just an array of X,Y and palette index triplets. The new chunk system divides the map up into square chunks, and lets each chunk manage its own memory layout. The "MapAccessor" layout is implemented first which is a map of X,Y coordinates to their Swatches (pointer to an index of the palette). When serialized the MapAccessor maps the "X,Y": "index" similarly to the old Pixels array. The object hierarchy for the chunk system is like: * Chunker: the manager of the chunks who keeps track of the ChunkSize and a map of "chunk coordinates" to the chunk in charge of it. * Chunk: a part of the drawing ChunkSize length square. A chunk has a Type (of how it stores its data, 0 being a map[Point]Swatch and 1 being a [][]Swatch 2D array), and the chunk has an Accessor which implements the underlying type. * Accessor: an interface for a Chunk to provide access to its pixels. * MapAccessor: a "sparse map" of coordinates to their Swatches. * GridAccessor: TBD, will be a "dense" 2D grid of Swatches. The JSON files are loaded in two passes: 1. The chunks only load their swatch indexes from disk. 2. With the palette also loaded, the chunks are "inflated" and linked to their swatch pointers. Misc changes: * The `level.Canvas` UI widget switches from the old Grid data type to being able to directly use a `level.Chunker` * The Chunker is a shared data type between the on-disk level format and the actual renderer (level.Canvas), so saving the level is easy because you can just pull the Chunker out from the canvas. * ChunkSize is stored inside the level file and the default value is at balance/numbers.go: 1000
2018-09-23 22:20:45 +00:00
// Default chunk size for canvases.
ChunkSize = 128
// Default size for a new Doodad.
DoodadSize = 100
// Size of Undo/Redo history for map editor.
UndoHistory = 20
// Options for brush size.
BrushSizeOptions = []int{
0,
1,
2,
4,
8,
16,
24,
32,
48,
64,
}
DefaultEraserBrushSize = 8
MaxEraserBrushSize = 32 // the bigger, the slower
// Default font filename selected for Text Tool in the editor.
// TODO: better centralize font filenames, here and in theme.go
TextToolDefaultFont = SansSerifFont
// Interval for auto-save in the editor
AutoSaveInterval = 5 * time.Minute
// Default player character doodad in Play Mode.
PlayerCharacterDoodad = "boy.doodad"
// Levelpack and level names for the title screen.
DemoLevelPack = "assets/levelpacks/001000-TUTORIAL.levelpack"
DemoLevelName = []string{
"Tutorial 1.level",
"Tutorial 2.level",
"Tutorial 3.level",
}
// Level attachment filename for the custom wallpaper.
// NOTE: due to hard-coded "assets/wallpapers/" prefix in uix/canvas.go#LoadLevel.
CustomWallpaperFilename = "custom.b64img"
CustomWallpaperEmbedPath = "assets/wallpapers/custom.b64img"
// Publishing: Doodads-embedded-within-levels.
EmbeddedDoodadsBasePath = "assets/doodads/"
EmbeddedWallpaperBasePath = "assets/wallpapers/"
// File formats: save new levels and doodads gzip compressed
Zipfiles as File Format for Levels and Doodads Especially to further optimize memory for large levels, Levels and Doodads can now read and write to a ZIP file format on disk with chunks in external files within the zip. Existing doodads and levels can still load as normal, and will be converted into ZIP files on the next save: * The Chunker.ChunkMap which used to hold ALL chunks in the main json/gz file, now becomes the cache of "hot chunks" loaded from ZIP. If there is a ZIP file, chunks not accessed recently are flushed from the ChunkMap to save on memory. * During save, the ChunkMap is flushed to ZIP along with any non-loaded chunks from a previous zipfile. So legacy levels "just work" when saving, and levels loaded FROM Zip will manage their ChunkMap hot memory more carefully. Memory savings observed on "Azulian Tag - Forest.level": * Before: 1716 MB was loaded from the old level format into RAM along with a slow load screen. * After: only 243 MB memory was used by the game and it loaded with a VERY FAST load screen. Updates to the F3 Debug Overlay: * "Chunks: 20 in 45 out 20 cached" shows the count of chunks inside the viewport (having bitmaps and textures loaded) vs. chunks outside which have their textures freed (but data kept), and the number of chunks currently hot cached in the ChunkMap. The `doodad` tool has new commands to "touch" your existing levels and doodads, to upgrade them to the new format (or you can simply open and re-save them in-game): doodad edit-level --touch ./example.level doodad edit-doodad --touch ./example.doodad The output from that and `doodad show` should say "File format: zipfile" in the headers section. To do: * File attachments should also go in as ZIP files, e.g. wallpapers
2022-04-30 03:34:59 +00:00
DrawingFormat = FormatZipfile
// Zipfile drawings: max size of the LRU cache for loading chunks from
// a zip file. Normally the chunker discards chunks not loaded in a
// recent tick, but when iterating the full level this limits the max
// size of loaded chunks before some will be freed to make room.
// 0 = do not cap the cache.
ChunkerLRUCacheMax = 0
// Play Mode Touchscreen controls.
PlayModeIdleTimeout = 2200 * time.Millisecond
PlayModeAlphaStep = 8 // 0-255 alpha, steps per tick for fade in
PlayModeAlphaMax = 220
// Invulnerability time in seconds at respawn from checkpoint, in case
// enemies are spawn camping.
RespawnGodModeTimer = 3 * time.Second
// GameController thresholds.
GameControllerMouseMoveMax float64 = 20 // Max pixels per tick to simulate mouse movement.
GameControllerScrollMin float64 = 0.3 // Minimum threshold for a right-stick scroll event.
// Limits on the Flood Fill tool so it doesn't run away on us.
FloodToolVoidLimit = 600 // If clicking the void, +- 1000 px limit
FloodToolLimit = 1200 // If clicking a valid color on the level
// Eager render level chunks to images during the load screen.
// Originally chunks rendered to image and SDL texture on-demand, the loadscreen was
// added to eager load (to image) the whole entire level at once (SDL textures were
// still on demand, as they scroll into screen). Control this in-game with
// `boolProp eager-render false` and the loadscreen will go quicker cuz it won't
// load the whole entire level. Maybe useful to explore memory issues.
EagerRenderLevelChunks = true
// Number of chunks margin outside the Canvas Viewport for the LoadingViewport.
LoadingViewportMarginChunks = render.NewPoint(10, 8) // hoz, vert
CanvasLoadUnloadModuloTicks uint64 = 4
CanvasChunkFreeChoppingBlockTicks uint64 = 128 // number of ticks old a chunk is to free it
)
// Edit Mode Values
var (
// Number of Doodads per row in the palette.
UIDoodadsPerRow = 2
)