RLE Encoding Code Cleanup [PTO]
* For the doodad tool: skip the assets embed folder, the doodad binary doesn't need to include all the game's doodads/levelpacks/etc. and can save on file size. * In `doodad resave`, .doodad files with Vacuum() and upgrade their chunker from the MapAccessor to the RLEAccessor. * Fix a rare concurrent map read/write error in OptimizeChunkerAccessors.
This commit is contained in:
parent
4851730ccf
commit
6be2f86b58
|
@ -15,6 +15,7 @@
|
||||||
- [Build on macOS from scratch](#build-on-macos-from-scratch)
|
- [Build on macOS from scratch](#build-on-macos-from-scratch)
|
||||||
- [WebAssembly](#webassembly)
|
- [WebAssembly](#webassembly)
|
||||||
- [Build Tags](#build-tags)
|
- [Build Tags](#build-tags)
|
||||||
|
- [doodad](#doodad)
|
||||||
- [dpp](#dpp)
|
- [dpp](#dpp)
|
||||||
|
|
||||||
# Dockerfile
|
# Dockerfile
|
||||||
|
@ -373,6 +374,13 @@ Some tips to get a WASM build to work:
|
||||||
|
|
||||||
Go build tags used by this game:
|
Go build tags used by this game:
|
||||||
|
|
||||||
|
## doodad
|
||||||
|
|
||||||
|
This tag is used when building the `doodad` command-line tool.
|
||||||
|
|
||||||
|
It ensures that the embedded bindata assets (built-in doodads, etc.) do not
|
||||||
|
need to be bundled into the doodad binary, but only the main game binary.
|
||||||
|
|
||||||
## dpp
|
## dpp
|
||||||
|
|
||||||
The dpp tag stands for Doodle++ and is used for official commercial builds of
|
The dpp tag stands for Doodle++ and is used for official commercial builds of
|
||||||
|
|
10
Makefile
10
Makefile
|
@ -23,7 +23,7 @@ setup: clean
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
go build $(LDFLAGS) $(BUILD_TAGS) -o bin/sketchymaze cmd/doodle/main.go
|
go build $(LDFLAGS) $(BUILD_TAGS) -o bin/sketchymaze cmd/doodle/main.go
|
||||||
go build $(LDFLAGS) $(BUILD_TAGS) -o bin/doodad cmd/doodad/main.go
|
go build $(LDFLAGS) -tags=doodad -o bin/doodad cmd/doodad/main.go
|
||||||
|
|
||||||
# `make buildall` to run all build steps including doodads.
|
# `make buildall` to run all build steps including doodads.
|
||||||
.PHONY: buildall
|
.PHONY: buildall
|
||||||
|
@ -34,7 +34,7 @@ buildall: doodads build
|
||||||
build-free:
|
build-free:
|
||||||
gofmt -w .
|
gofmt -w .
|
||||||
go build $(LDFLAGS) -o bin/sketchymaze cmd/doodle/main.go
|
go build $(LDFLAGS) -o bin/sketchymaze cmd/doodle/main.go
|
||||||
go build $(LDFLAGS) -o bin/doodad cmd/doodad/main.go
|
go build $(LDFLAGS) -tags=doodad -o bin/doodad cmd/doodad/main.go
|
||||||
|
|
||||||
# `make bindata` generates the embedded binary assets package.
|
# `make bindata` generates the embedded binary assets package.
|
||||||
.PHONY: bindata
|
.PHONY: bindata
|
||||||
|
@ -75,7 +75,7 @@ mingw:
|
||||||
go build $(LDFLAGS_W) $(BUILD_TAGS) -o bin/sketchymaze.exe cmd/doodle/main.go
|
go build $(LDFLAGS_W) $(BUILD_TAGS) -o bin/sketchymaze.exe cmd/doodle/main.go
|
||||||
env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \
|
env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \
|
||||||
GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \
|
GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \
|
||||||
go build $(LDFLAGS) $(BUILD_TAGS) -o bin/doodad.exe cmd/doodad/main.go
|
go build $(LDFLAGS) -tags=doodad -o bin/doodad.exe cmd/doodad/main.go
|
||||||
|
|
||||||
# `make mingw32` to cross-compile a Windows binary with mingw (32-bit).
|
# `make mingw32` to cross-compile a Windows binary with mingw (32-bit).
|
||||||
.PHONY: mingw32
|
.PHONY: mingw32
|
||||||
|
@ -85,7 +85,7 @@ mingw32:
|
||||||
go build $(LDFLAGS_W) $(BUILD_TAGS) -o bin/sketchymaze.exe cmd/doodle/main.go
|
go build $(LDFLAGS_W) $(BUILD_TAGS) -o bin/sketchymaze.exe cmd/doodle/main.go
|
||||||
env CGO_ENABLED="1" CC="/usr/bin/i686-w64-mingw32-gcc" \
|
env CGO_ENABLED="1" CC="/usr/bin/i686-w64-mingw32-gcc" \
|
||||||
GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \
|
GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \
|
||||||
go build $(LDFLAGS) $(BUILD_TAGS) -o bin/doodad.exe cmd/doodad/main.go
|
go build $(LDFLAGS) -tags=doodad -o bin/doodad.exe cmd/doodad/main.go
|
||||||
|
|
||||||
# `make mingw-free` for Windows binary in free mode.
|
# `make mingw-free` for Windows binary in free mode.
|
||||||
.PHONY: mingw-free
|
.PHONY: mingw-free
|
||||||
|
@ -95,7 +95,7 @@ mingw-free:
|
||||||
go build $(LDFLAGS_W) -o bin/sketchymaze.exe cmd/doodle/main.go
|
go build $(LDFLAGS_W) -o bin/sketchymaze.exe cmd/doodle/main.go
|
||||||
env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \
|
env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \
|
||||||
GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \
|
GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \
|
||||||
go build $(LDFLAGS) -o bin/doodad.exe cmd/doodad/main.go
|
go build $(LDFLAGS) -tags=doodad -o bin/doodad.exe cmd/doodad/main.go
|
||||||
|
|
||||||
# `make release` runs the release.sh script, must be run
|
# `make release` runs the release.sh script, must be run
|
||||||
# after `make dist`
|
# after `make dist`
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
//go:build !doodad
|
||||||
|
// +build !doodad
|
||||||
|
|
||||||
// Package assets gets us off go-bindata by using Go 1.16 embed support.
|
// Package assets gets us off go-bindata by using Go 1.16 embed support.
|
||||||
//
|
//
|
||||||
// For Go 1.16 embed, this source file had to live inside the assets/ folder
|
// For Go 1.16 embed, this source file had to live inside the assets/ folder
|
||||||
|
|
32
assets/assets_omitted.go
Normal file
32
assets/assets_omitted.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//go:build doodad
|
||||||
|
// +build doodad
|
||||||
|
|
||||||
|
// Dummy version of assets_embed.go that doesn't embed any files.
|
||||||
|
// For the `doodad` tool.
|
||||||
|
|
||||||
|
package assets
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Embedded embed.FS
|
||||||
|
|
||||||
|
var errNotEmbedded = errors.New("assets not embedded")
|
||||||
|
|
||||||
|
// AssetDir returns the list of embedded files at the directory name.
|
||||||
|
func AssetDir(name string) ([]string, error) {
|
||||||
|
return nil, errNotEmbedded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asset returns the byte data of an embedded asset.
|
||||||
|
func Asset(name string) ([]byte, error) {
|
||||||
|
return nil, errNotEmbedded
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssetNames dumps the names of all embedded assets,
|
||||||
|
// with their legacy "assets/" prefix from go-bindata.
|
||||||
|
func AssetNames() []string {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -101,6 +101,12 @@ func resaveDoodad(c *cli.Context, filename string) error {
|
||||||
filename = output
|
filename = output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := dd.Vacuum(); err != nil {
|
||||||
|
log.Error("Vacuum error: %s", err)
|
||||||
|
} else {
|
||||||
|
log.Info("Run vacuum on doodad file.")
|
||||||
|
}
|
||||||
|
|
||||||
log.Info("Saving back to disk")
|
log.Info("Saving back to disk")
|
||||||
if err := dd.WriteJSON(filename); err != nil {
|
if err := dd.WriteJSON(filename); err != nil {
|
||||||
return fmt.Errorf("couldn't write %s: %s", filename, err)
|
return fmt.Errorf("couldn't write %s: %s", filename, err)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
const (
|
const (
|
||||||
AppName = "Sketchy Maze"
|
AppName = "Sketchy Maze"
|
||||||
Summary = "A drawing-based maze game"
|
Summary = "A drawing-based maze game"
|
||||||
Version = "0.14.0"
|
Version = "0.14.1"
|
||||||
Website = "https://www.sketchymaze.com"
|
Website = "https://www.sketchymaze.com"
|
||||||
Copyright = "2023 Noah Petherbridge"
|
Copyright = "2023 Noah Petherbridge"
|
||||||
Byline = "a game by Noah Petherbridge."
|
Byline = "a game by Noah Petherbridge."
|
||||||
|
|
14
pkg/doodads/fmt_maintenance.go
Normal file
14
pkg/doodads/fmt_maintenance.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package doodads
|
||||||
|
|
||||||
|
// Vacuum runs any maintenance or migration tasks for the level at time of save.
|
||||||
|
//
|
||||||
|
// It will prune broken links between actors, or migrate internal data structures
|
||||||
|
// to optimize storage on disk of its binary data.
|
||||||
|
func (m *Doodad) Vacuum() error {
|
||||||
|
// Let the Chunker optimize accessor types.
|
||||||
|
for _, layer := range m.Layers {
|
||||||
|
layer.Chunker.OptimizeChunkerAccessors()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -164,6 +164,11 @@ func (d *Doodad) WriteFile(filename string) error {
|
||||||
d.Version = 1
|
d.Version = 1
|
||||||
d.GameVersion = branding.Version
|
d.GameVersion = branding.Version
|
||||||
|
|
||||||
|
// Maintenance functions, clean up cruft before save.
|
||||||
|
if err := d.Vacuum(); err != nil {
|
||||||
|
log.Error("Vacuum level %s: %s", filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
bin, err := d.ToJSON()
|
bin, err := d.ToJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -36,8 +36,11 @@ func (c *Chunker) OptimizeChunkerAccessors() {
|
||||||
ma, _ := chunk.Accessor.(*MapAccessor)
|
ma, _ := chunk.Accessor.(*MapAccessor)
|
||||||
rle := NewRLEAccessor(chunk).FromMapAccessor(ma)
|
rle := NewRLEAccessor(chunk).FromMapAccessor(ma)
|
||||||
|
|
||||||
|
// Lock the chunker for updating.
|
||||||
|
c.chunkMu.Lock()
|
||||||
c.Chunks[point].Type = RLEType
|
c.Chunks[point].Type = RLEType
|
||||||
c.Chunks[point].Accessor = rle
|
c.Chunks[point].Accessor = rle
|
||||||
|
c.chunkMu.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user