Author SHA1 Message Date
YourWishesandClaude Sonnet 5 9a24b3d7db Bring the entity-component system online: rendering, scene manager, scripting
entityRenderAll() (src/dusk/entity/entityrender.c) ports ac2's
scene.c:sceneRender() camera/view-matrix/draw-loop logic as a standalone
function - find the active camera, bind SHADER_UNLIT with its projection/
view, draw every COMPONENT_TYPE_RENDERABLE entity. display.c calls it each
frame between the screen clear and screenUnbind(), the same spot the old
sceneRender() used to sit.

A single-scene scene manager (src/dusk/scene/, ported from ac2 minus its
prefab system and physics/trigger stepping - that module hasn't been
ported yet) sits alongside this but isn't wired into the engine loop yet;
only one scene can ever exist (no SCENE_COUNT_MAX array).

entitymanager.c/h removed entirely: its three arrays (entities/components/
entitiesWithComponent) are now plain globals in entity.h/.c
(ENTITIES/COMPONENTS/ENTITIES_WITH_COMPONENT), and every entity/component
function across the whole ECS (entity, component, position, camera,
renderable, physics, trigger, animation) drops its entitymanager_t *mgr
parameter to operate on them directly - there was only ever one instance of
that struct in the whole engine, so the indirection bought nothing.

New duskscript bindings (src/dusk/script/native/entity/) expose entityAdd,
entityAddComponent/entityGetComponent, entitySetName/entityGetName/
entityFindByName, entityDispose/entityDisposeDeep,
entityPositionSetLocalPosition/entityPositionLookAt,
entityRenderableSetMesh (by name - cube/plane/sphere/capsule/triprism/quad),
and COMPONENT_TYPE_*/ENTITY_ID_INVALID/COMPONENT_ID_INVALID constants.
assets/init.ds uses them to spawn a camera (via LookAt from (3,3,3) at the
origin), a cube and a plane as the engine's first real content on the new
ECS.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-15 09:08:20 -05:00
YourWishesandClaude Sonnet 5 fdfdfa3a66 Fix the build after archiving rpg/ui/scene: drop their last live dependents
rpg/ui/scene moved to archive/ earlier left a handful of otherwise-generic
systems with dead references into them:
- asset/loader/chunk existed solely to load rpg overworld map chunks
  (tile_t, worldpos_t) - deleted outright, along with its
  ASSET_LOADER_TYPE_CHUNK entry in assetloader.c/h.
- save/slot wrapped party_t/storyflagval_t/map-name/cutscene-path, which is
  100% rpg save data - deleted outright (save.c/h, savedevice.c/h and the
  Linux save backend keep their generic settings/device-discovery logic,
  just lose the slot read/write pieces that only existed for it).
- locale/localemanager.c and test/CMakeLists.txt/test/save/* had a few
  stray includes and test cases that only existed for the now-gone code.

Also restores assets/locale/en_US.po (copied back from archive/assets/) -
locale init still needs a real locale file to boot into, even with the
asset-moving/archiving done separately.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-15 09:08:02 -05:00
YourWishesandClaude Sonnet 5.5 f6b884bf7f Allow script arrays to hold any value type, add script engine tests, archive old rpg code
Remove the per-array type category so arrays can mix types like structs.
Add 13 passing and 125 expected-failure duskscript test fixtures with a
table-driven runner. Also includes the in-progress entity/physics and
archive moves from the working tree.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-14 23:25:26 -05:00
YourWishesandClaude Sonnet 5 5c259e46e2 init.ds: print Test to confirm it runs on boot
Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 22:59:42 -05:00
YourWishesandClaude Sonnet 5 00b73050ad Run init.ds from engineInit once every other system is ready
assets/init.ds is compiled and packed as init.dsb like any other script, and
engineInit() runs it as the very last init step - after scriptInit() and
sceneInit(), right before the initial scene is set - so it's free to use any
engine system (display, audio, save, rpg, ui, scenes, ...) without having to
special-case startup ordering. A syntax error or runtime failure in init.ds
is fatal, same as every other errorChain()'d init step.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 22:33:50 -05:00
YourWishesandClaude Sonnet 5 a0294aae98 Load duskscript files through the asset system, not the real filesystem
scriptLoadHandler used fopen/fread directly, but every .ds a script include()s
is packed into dusk.dsk (compiled to .dsb) like every other asset now, not a
loose file next to the binary - raw filesystem reads never found them outside
a dev checkout. It now goes through assetFileInit/Open/Read/Close like the
rest of the engine's asset loaders, failing the load the same way (returning
SCRIPT_LOAD_FAILED) for a missing entry or one bigger than capacity.

test_duskscript's fixtures moved to their own assets/ subfolder and pack into
a small test.dsk with the same tools.asset.pack used for the real dusk.dsk,
and the test opens that archive straight into ASSET.zip (skipping the full
assetInit()/assetInitPlatform(), which expects a launched engine) so the
tests exercise the real compile -> pack -> asset -> runtime pipeline instead
of a filesystem shortcut around it.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 22:33:46 -05:00
YourWishesandClaude Sonnet 5 5cf0678429 Subdirify src/dusk/script's core/ and vm/ CMakeLists
core/CMakeLists.txt and vm/CMakeLists.txt each listed every .c file across
every sub-folder in one flat target_sources() call. Split that into one
add_subdirectory() per folder (array, bytecode, call, coroutine, error, gc,
heap, number, ops, promise, runtime, scope, string, struct, text, value and
builtin/{array,core,math,string} under core/; execute, image and ops under
vm/), each with its own small CMakeLists.txt listing just that folder's
sources - matching the convention already used in src/dusk/display/.

Verified the Dusk binary and the duskscript test suite still build and pass
identically; test_battle and test_entityinteract already failed the same
way before this change (stale against unrelated rpg/battle API changes), so
left untouched here.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 15:00:16 -05:00
YourWishesandClaude Sonnet 5 7e932e67a2 Compile .ds scripts under assets/ to .dsb before packing into dusk.dsk
tools/asset/pack now special-cases .ds files: each one is compiled with
duskscriptcc to a temp .dsb (no .map, nothing reads one yet) and that gets
packed under the same path with the extension swapped - the raw .ds source
never ends up in the archive. Every other asset type is unchanged, packed
byte for byte as before.

CMake passes --duskscriptcc "$<TARGET_FILE:duskscriptcc>" and adds a DEPENDS
on it, but only on the linux/knulli host target where duskscriptcc is
actually built (see its own gating in src/CMakeLists.txt) - a cross-compiled
console target has no host-built compiler to point at, so for now it can
only pack an assets/ with no .ds in it; the packer raises a clear error
rather than silently skipping or mis-packing one if it finds one anyway.

The manifest's cache-skip check also now folds in duskscriptcc's own mtime,
so a compiler rebuild invalidates every .ds's cached result even when none
of their own source files changed.

Verified by hand: a .ds under assets/scripts/ packs as the matching .dsb
(confirmed by unzipping the resulting dusk.dsk), an unrelated rebuild
correctly skips re-packing, touching duskscriptcc correctly forces a
re-pack, and a syntax error in the .ds fails the build loudly with
duskscriptcc's own error message rather than silently succeeding.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 14:21:20 -05:00
YourWishesandClaude Sonnet 5 d878463ccb Make script.h the one include for everything duskscript-related
Folds what used to be duskscriptnative.h's includes (builtin/value/array/
struct/promise helpers a native function needs) directly into script.h,
alongside the runtime and VM includes already there. scriptnativeconsole.h
now just includes "script/script.h" instead of enumerating the same list
itself - any new native function bindings can do the same.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 13:54:08 -05:00
YourWishesandClaude Sonnet 5 5d8337af7e Always build and init duskscript, remove the DUSK_SCRIPT option
Scripting is now a standard part of the engine rather than an optional
feature: removes the DUSK_SCRIPT CMake option and its compile definition,
makes src/dusk/CMakeLists.txt add_subdirectory(script) unconditionally, and
drops the #ifdef DUSK_SCRIPT guards around scriptInit()/scriptDispose() in
engine.c. duskscriptcc and its test still only build on the linux/knulli
host target (it's a dev tool, not part of the runtime), now gated on that
alone instead of DUSK_SCRIPT AND that.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 13:54:02 -05:00
YourWishesandClaude Sonnet 5 6d056560e7 Remove duskscriptnative.h, move scriptnativeconsole into src/dusk/script/native/
duskscriptnative.h had exactly one consumer (scriptnativeconsole.h) left
after the duskscriptvm.h removal; folds its includes in directly rather than
keeping a single-consumer indirection.

Moves scriptnativeconsole.c/.h into their own native/ subdirectory, giving
it the same add_subdirectory(native) + CMakeLists.txt treatment as core/
and vm/, so future native function bindings have an obvious home.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 13:48:07 -05:00
YourWishesandClaude Sonnet 5 4d2d57fdb4 Remove duskscriptvm.h, fold its includes into script.h
It had exactly one consumer (script.h) and added nothing of its own beyond
re-including duskscript.h + image/scriptvmattach.h + image/scriptvmrun.h -
a pointless indirection now that it's not a standalone embedding SDK with
multiple external consumers.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 13:43:50 -05:00
YourWishesandClaude Sonnet 5 d35058598c Split the ported "types dump" headers into one type per file
scriptvmtypes.h, scriptcompiletypes.h and scriptnode.h each crammed several
unrelated struct definitions into one file, unlike the rest of dusk (see
src/dusk/display or src/dusk/rpg/battle), which always gives a type its own
file named after it, with other types reached by an explicit include or a
forward declaration.

- scriptvmtypes.h: scriptvmfunction_t moves into scriptvmfunction.h (next to
  the functions that already work with it), scriptvmname_t into
  scriptvmname.h, scriptvmhandler_t into scriptvmtable.h, and scriptvmimage_t
  gets a new scriptvmimage.h. scriptvmtypes.h keeps working as a thin
  re-include umbrella for the ~45 vm files that reach into several of these
  at once, the same role scripttypes.h already plays for the base types.

- scriptcompiletypes.h: scriptlabel_t moves into scriptbuilderlabel.h,
  scriptloopcontext_t into scriptcompileloopcontext.h, scriptincluderesolver_t
  into scriptcompile.h, and the big scriptbuilder_t gets a new scriptbuilder.h.
  Breaking the resulting include cycle needed scriptbuilderlabel.h and
  scriptcompileloopcontext.h to forward-declare scriptbuilder_t/scriptlabel_t
  rather than pull in full definitions they only ever use by pointer, and
  scriptcompile.h to define scriptincluderesolver_t before including
  scriptcompiletypes.h instead of after.

- scriptnode.h: scriptfuncnode_t (a function declaration, not a kind of
  expression/statement node) moves into a new scriptfuncnode.h.

Also gives scriptbuilder_t and scriptlabel_t proper struct tags (previously
anonymous, which doesn't allow forward declaration) to match the project's
_s tag / _t typedef convention from the previous pass.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 13:40:30 -05:00
YourWishesandClaude Sonnet 5 af2f0617e0 Consistency pass: house struct tags, pragma once guards, pack bools into flags
Struct tags throughout duskscript reused the typedef name itself (struct
foo_t { ... }), unlike the rest of dusk which always tags with foo_s and
typedefs foo_t - renames all 15 tagged structs in src/dusk/script and
src/duskscriptcc to match. Also drops a vestigial duplicate forward
declaration of scriptsource_t left over from the port.

Unifies all 144 #ifndef/#define/#endif include guards in the ported code to
#pragma once, matching the rest of the codebase (which was already a mix of
25 files doing it the house way and 144 not).

Packs scriptvmfunction_t's isAsync/isRoot/isScript and scriptfuncnode_t's
isAsync/isInline/isNoInline/isRoot/isScript into single uint8_t flags
fields with bit constants, mirroring the SCRIPT_BINARY_FLAG_ASYNC pattern
the bytecode format already uses and the flags-byte convention used
elsewhere in dusk (animation, display). While there, zero-initializes both
scriptfuncnode_t allocation sites (scriptAlloc never zeroes memory, so
several of its fields - not just the ones being packed here - were
previously read uninitialized before their first explicit write), and
removes scriptfunction_t's dead `plain` field, which was always the exact
inverse of isAsync and never actually read anywhere.

Converts the couple of struct-level doc comments that used the ported
project's Javadoc-with-@param style to dusk's plain // prose convention,
and adds missing rationale comments to scriptruntime_t and scriptstring_t,
which had none at all.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 13:22:39 -05:00
YourWishesandClaude Sonnet 5 703d89a9ac Consistency pass: fix util/memory.h include ordering, drop stray comment and unused include
util/memory.h had landed as the very first #include in ~30 files from the
mechanical memcpy/memcmp conversion, ahead of each file's own umbrella type
header - moves it back after, matching the rest of the codebase's ordering.
Also updates a scriptplatform.h comment left over from the int/fixed/bignum
split, and drops an unused util/string.h include in scriptcompile.c.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 13:05:06 -05:00
YourWishesandClaude Sonnet 5 c1d6a97293 Port the duskscript language into the engine as src/dusk/script + duskscriptcc
Brings over the duskscript VM and compiler from dusk-vm: the runtime
(core/vm) lives under src/dusk/script, gated by DUSK_SCRIPT and wired into
the engine lifecycle with print()/consolePrint() routed to the console; the
standalone duskscriptcc compiler stays a lean host tool (linux/knulli only).

Collapses int/fixed/bignum into a single float-backed SCRIPT_VALUE_NUMBER
throughout the lexer, compiler, bytecode format and VM, removing the old
int16-rollover fast paths and the type-conversion builtins they needed.

Fixes a real big-endian bug in the bytecode's 32-bit number reader (found
while adding GameCube/Wii endian support via util/endian.h) and converts
src/dusk/script and duskscriptcc to dusk's memory/string/assert utilities,
which surfaced two more latent bugs: a conservative GC stack scan reading
its own local variable's address, and an uninitialized path buffer in
scriptReadScript when the caller path has no directory component.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-14 12:59:46 -05:00
YourWishesandClaude Sonnet 5 3948607b1e Rename cutscenesystemrefs_t to cutsceneref_t, cutsceneRefsReset to cutsceneRefReset, and cutscenerefs.c/.h to cutsceneref.c/.h
Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 10:23:38 -05:00
YourWishes 6c180372fe First pass cleaning cutscene system. 2026-09-25 09:57:48 -05:00
YourWishesandClaude Sonnet 5 fed04b66b8 Persist and resume in-progress cutscene via save slot; add species stub
Save slots now track the currently-active cutscene file (defaulting to a
new placeholder new_game.jsonc intro) so loading a save resumes it;
cutsceneSystemStartCutsceneWith persists this on every cutscene start, and
a cutsceneSystemLoad ordering bug (loadedFile stamped after starting) is
fixed so the persisted path is always correct. Also adds a
battlefighterspecies_t/battlespeciesid_t stub for upcoming species data.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-22 18:44:45 -05:00
YourWishesandClaude Sonnet 5 a4ca718070 Add shared battleFighterParse/Serialize, use it everywhere a fighter is (de)serialized
Replaces three independently hand-rolled battlefighter_t JSON readers/
writers (party.jsonc roster loading, BATTLE_START enemy definitions, and
the v1 save-file party member format) with one generic pair in
battlefighter.c: battleFighterParse(fighter, obj) and its inverse
battleFighterSerialize(fighter, doc). Covers team/controller/status
(optional, default ally/player/normal), the 7 base stats (required),
current health/mp (optional, default to max), and an optional abilities
name array.

- party.c: partyInit now parses each roster member via battleFighterParse
  directly, dropping the old partyParseStats/partyParseStatField.
- cutscenebattlestart.c/.h: cutscenebattlestartenemy_t now embeds a full
  battlefighter_t, parsed once at Load time; Start just copies it into the
  enemy pool instead of re-initializing. battletest.jsonc's enemies are
  now flat (dropped the "stats" wrapper) to match.
- saveslotver1.c/.h: rewritten in place to use the shared parser/
  serializer, changing the v1 on-disk field names/shape (no migration -
  acceptable pre-release, documented in saveslotver1.h).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-22 14:20:45 -05:00
YourWishesandClaude Sonnet 5 8dbd3e1dd2 Key-based party roster, show party member names in battle UI
- party.jsonc's "members" is now a key/value object (e.g. "hero",
  "companion") instead of an array - partyInit seeds party_t.keys
  alongside members, and partyGetMemberIndexByKey/partyGetMemberKey do the
  lookups. Cutscene items (PARTY_ADD_MEMBER/PARTY_REMOVE_MEMBER/
  PARTY_HEAL_MEMBER) now take a "key" JSON field, resolved to a roster
  index at load time, instead of a raw index.
- Battle UI shows who's acting: uibattlemenu.c draws the current fighter's
  party key above the action menu, and uibattlehud.c draws each ally
  fighter's key as an extra line above their HP/MP.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 22:38:04 -05:00
YourWishesandClaude Sonnet 5 7a9a2b9832 Add order-based party roster, back-navigation in battle selection, fix win-state cutscene leak
- Battle selection menu can now go back a fighter to re-decide their move,
  and battle win/loss no longer leaks the round's remaining queued move
  cutscenes into the ending state (cutsceneSystemDiscardQueued).
- Party roster is now driven by party.jsonc: every defined member always
  exists (partyInit), while party->order alone determines who's currently
  active - partyAddMember/partyRemoveMember (and their cutscene items) now
  activate/deactivate an existing roster member by index instead of
  creating/destroying one, with removal compacting order to stay packed.
- New PARTY_ADD_MEMBER/PARTY_REMOVE_MEMBER/PARTY_HEAL_MEMBER/PARTY_HEAL_ALL
  cutscene items.
- saveSlotInit/partyInit now return errorret_t and take their target
  struct directly (saveslot_t*/party_t*) instead of implicitly operating
  on SAVE.slot; saveSlotReadJSON resets through saveSlotInit rather than
  duplicating the reset logic.
- Test coverage: stub the JSON asset loader in save test fixtures so
  partyInit's real party.jsonc load runs against an in-memory doc instead
  of hanging with no asset system initialized.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 22:27:46 -05:00
YourWishes e8757c33e3 Fix U_IDLE asset error from cutscene item pointer aliasing
cutsceneCutsceneResolve and cutsceneSystemLoad could be called with a
name/path pointer that aliases into CUTSCENE_SYSTEM.loadedItems (e.g. a
CUTSCENE item's own name field). cutsceneLoadParse then overwrites that
same buffer while loading the target cutscene, so the subsequent
stringCopy into loadedFile read stale, corrupted memory. Copy the
name/path into a local buffer before use in both functions.
2026-09-21 19:48:28 -05:00
YourWishes b498a12458 Merge branch 'battle-refactor' 2026-09-21 15:04:52 -05:00
YourWishesandClaude Sonnet 5 c9f098693c Wire up battle AI/scene-return, reclaim cutscene item slots, fix GOTO
- battleStateSelectionAiDecide: AI-controlled fighters now actually
  queue a basic attack against the first living enemy instead of doing
  nothing every round.
- battleStateEndingInit: disposes the battle and switches back to
  SCENE_TYPE_OVERWORLD instead of leaving the game stuck in the battle
  scene forever.
- cutsceneSystemNext now pops each finished item off the front of the
  running cutscene (cutsceneRemoveFront) instead of leaving it in place
  forever, so a long-running cutscene (many battle rounds splicing
  items in repeatedly) no longer grows scene->items unboundedly.
- cutsceneGoTo reworked to match: since consumed items are evicted, a
  marker behind the current position can't be found in the live queue
  anymore, so it now re-parses the cutscene fresh from its source file
  (cutsceneLoadParse, into a persistent scratch buffer, not the stack)
  and replaces the live queue with marker-onward from that fresh parse.
  Only supported when the running cutscene is the one
  cutsceneSystemLoad/cutsceneCutsceneResolve populated.
- Fixed a real bug this surfaced: cutsceneSystemPrepare unconditionally
  cleared loadedFile, which ran *after* cutsceneCutsceneResolve had
  just stamped it but *before* the cutscene started - wiping it out
  immediately and breaking cutsceneGoTo for any cutscene entered via a
  CUTSCENE item or cutsceneCutsceneResolve (e.g. the main menu's
  NEW_GAME/OPTIONS/QUIT navigation). Now only cleared when switching
  away from loadedScene entirely.
- Added cutsceneLoadParse, the shared "lock asset, require loaded,
  parse items, unlock" sequence, replacing four near-identical copies
  across cutsceneSystemLoad/cutsceneCutsceneResolve/
  cutsceneInsertResolveAndSplice/battleStateExecutingInit. Each call
  site handles its own fatal-error display; cutsceneLoadParse itself
  just propagates.
- Added test_cutscene.c (cutsceneRemoveFront) and a regression test for
  the loadedFile bug. Writing the zero-count RemoveFront test caught a
  real self-move bug (count == 0 passed dest == src into memoryMove).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 15:04:41 -05:00
YourWishesandClaude Sonnet 5 7aeffac9fc Add battle fighter damage/heal cutscene items, wire up battle results
BATTLE_FIGHTER_DAMAGE/BATTLE_FIGHTER_HEAL let a move's own cutscene
apply damage/healing to "target" or "user", resolved from
BATTLE_FIGHTER_POS_TARGET/USER sentinels against the current action by
battleStateExecutingInit. fire/slash now call BATTLE_FIGHTER_DAMAGE on
their target.

BATTLE_POST_MOVE checks fighter health after each move and sets
BATTLE.result (now a real field, previously commented out) to
win/loss, transitioning into BATTLE_STATE_WON/LOST; fleeing sets
BATTLE_RESULT_FLED. All three end states now show a textbox before
moving on to BATTLE_STATE_ENDING.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 21:14:00 -05:00
YourWishesandClaude Sonnet 5 37e7e95ace Resolve moves into per-move cutscenes during battle execution
Each queued action now resolves to its move's cutscene
(cutscenes/battle/moves/<name>.jsonc), spliced into the executing state
with a BATTLE_POST_MOVE checkpoint after each one. Fighter turn order is
tracked via fighterOrder/fighterOrderCount, and resolved actions/pending
counts are cleared so fighters aren't skipped in later rounds. Also fixes
a BATTLE_WAIT_SELECTION deadlock and adds an optional "blocking" flag to
MODAL cutscene items.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 17:49:06 -05:00
YourWishesandClaude Sonnet 5 e3f56c4d12 Drive battle rounds through cutscene items, fix render/init bugs
Adds BATTLE_START, BATTLE_SET_STATE and BATTLE_WAIT_SELECTION cutscene
items so a battle's state transitions (opening -> pre-round -> selection
-> executing) are chained through the running cutscene, with
cutsceneSystemInsertItemsNext/InsertItems splitting "splice" from
"splice and advance immediately". Adds battlestateselection's
get-current-fighter/player-attack/player-flee API backing the battle UI,
and battleMoveGetIdByName for JSON-authored ability lookups.

Fixes: off-by-one in battleMoveInit that let the first-defined move
alias BATTLE_MOVE_ID_NULL; a segfault in scenebattle.c from rendering
unfilled (NULL) fighter slots; stale battleGetCurrentFighter/
battlePlayerAttack/battlePlayerFlee references in the battle UI.

Adds assertions across the battle/scene/UI code for fighter-index
bounds and non-null invariants. Updates battletest.jsonc for the new
BATTLE_START item schema.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 13:32:52 -05:00
YourWishesandClaude Sonnet 5 3675ec634f Rework battle system: pointer-based fighters, per-state files, move split
Splits battlemoveaction_t into its own header, adds a per-state
struct/init/update/dispose file under rpg/battle/state driven by a
dispatch table, switches BATTLE.fighters to battlefighter_t* backed by a
pool, folds current/max health and mp into battlefighterstats_t, and adds
battleFighterDamage/Heal/AbilityAdd. Removes the now-unused battle
cutscene items (START_BATTLE, BATTLE_WAIT_STATE, BATTLE_FORCE_MOVE,
REGULAR_BATTLE) and their JSON lookup helpers, and adds JSON validation
to battleMoveInit. battle.h/battle.c are mid-rewrite around the new state
machine, so some UI consumers (uibattlehud.c, uibattlemenu.c) and
test_battle.c are currently out of sync with the new API.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-19 23:17:27 -05:00
YourWishes d8273a225c Battle changes, first pass. 2026-09-19 22:30:01 -05:00
YourWishesandClaude Sonnet 5 c1c8174b27 Use CUTSCENE/INSERT item names as full asset paths directly
cutsceneCutsceneResolve/cutsceneInsertResolveAndSplice no longer inject
a "cutscenes/%s.jsonc" prefix/suffix around an item's "name" field -
matching cutsceneSystemLoad, which already takes a full path. Fixes a
latent double-prefix bug in initial.jsonc's CUTSCENE reference (also had
a "jsonsc" typo) that this change would otherwise have exposed.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-19 21:38:09 -05:00
YourWishes 5697f5c064 Fix main menu crash 2026-09-19 21:33:21 -05:00
YourWishesandClaude Sonnet 5 3ce16cf7f4 Fix uilabel dirty bug and add word-wrap support
uiLabelInit now marks a fresh label dirty itself, instead of every call
site having to remember to do it. Adds uiLabelSetWrap (NULL buffer
disables wrapping, otherwise requires a positive width) built on the
existing textWrap(), and wires the fatal error overlay's message label
up to wrap at 80% of screen width.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-19 21:32:24 -05:00
YourWishes 2abd5b0c3c Beginning a bit of cleanup 2026-09-19 21:17:11 -05:00
YourWishesandClaude Sonnet 5 4b29bf7a30 Wire story flags into the save slot and add cutscene controls
Implements storyInit/storyGetFlagByName/storyGetFlagValue/etc, moves flag
storage into saveslot_t (persisted keyed by name so save files survive
flag reordering), and adds STORY_SET_FLAG/STORY_WAIT_FLAG cutscene items.
Also removes the now-superseded storyflag.c/h stub.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-19 20:39:53 -05:00
YourWishes 6f1bbe4f2f First pass story flags 2026-09-19 10:45:06 -05:00
YourWishesandClaude Sonnet 5 f64364f37d Trim cutscenesystem.h doc comments to the essentials
Comments-only change - drops implementation rationale/cross-referencing
detail in favor of shorter one-liners, matching the simplified style
already applied to part of the file.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-18 11:21:12 -05:00
YourWishesandClaude Sonnet 5 d16e0bbfbf Stop stealing/reaping cutscene JSON docs - parse in place instead
cutsceneSystemLoad, cutsceneCutsceneResolve and
cutsceneInsertResolveAndSplice all used to steal ownership of the
asset entry's parsed yyjson_doc (nulling entry->data.json) and force
an immediate assetReapUnused() to avoid handing back a corrupted
cache entry on a later load of the same file - which doubled as a
latent crash if that reap was ever skipped (as it briefly was),
since a stale cache hit would then have a NULL doc.

Turns out none of that was needed: every cutsceneitem_t field that
could reference the doc's memory already copies its string data by
value (cutsceneJsonCopyString into fixed buffers), so the parsed
items don't depend on the doc surviving past cutsceneParseDoc. All
three call sites now parse straight out of entry->data.json while
still locked, then unlock normally - the asset entry stays a normal,
correctly-cached resource, and CUTSCENE_LOADED_DOC/cutsceneLoadedSetDoc
are gone entirely.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-18 09:47:05 -05:00
YourWishesandClaude Sonnet 5 70ae41bd29 Track the loaded cutscene filename and re-load it on restart
Adds CUTSCENE_SYSTEM.loadedFile, set by cutsceneSystemLoad and cleared
by cutsceneSystemPrepare. cutsceneRestart now re-reads and re-parses
that file via cutsceneSystemLoad instead of just rerunning whatever's
still resident in loadedScene/loadedItems, so restarting a file-loaded
cutscene always reflects its current on-disk contents - restart of a
C-authored cutscene is unchanged.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-18 09:28:15 -05:00
YourWishesandClaude Sonnet 5 abf6863044 Assert NULL pointer/marker args in cutscenesystem.c entry points
Matches the existing assertNotNull convention in cutscene.c
(cutsceneAppend/cutsceneParseDoc etc.) - these are internal-API
preconditions on trusted callers, not untrusted input.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-18 09:09:35 -05:00
YourWishesandClaude Sonnet 5 4279bd9675 Remove unused CUTSCENE_SYSTEM.userData scratch buffer
Nothing ever wrote to it - it only ever passed its own address through
to onComplete/CUTSCENE_CALLBACK/modal-option callbacks, so every call
site now passes NULL directly and the 8KB buffer is gone.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-17 22:32:09 -05:00
YourWishesandClaude Sonnet 5 5910110b95 Rework CUTSCENE_ITEM_TYPE_INSERT to splice into the running scene's item array
Replaces the separate insert buffer/scene and insertStack return-frame
mechanism with cutsceneAppend/cutsceneAppendNext, so an inserted
cutscene's items become part of the running scene's own array instead
of a jump-and-return. Moves the loaded-items buffer/scene from file-scope
globals into cutscenesystem_t, and extracts shared start-cutscene setup
into cutsceneSystemPrepare.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-17 22:26:36 -05:00
YourWishesandClaude Sonnet 5 44594f7011 Add cutsceneAppend/cutsceneAppendNext for mutating a running cutscene
cutsceneAppend adds items to the end of a cutscene_t's item array;
cutsceneAppendNext inserts them at a given index instead (e.g.
CUTSCENE_SYSTEM.currentItem + 1, to run immediately after the
currently-executing item), shifting everything from that index
onward to make room. Both are capacity-bounded against the caller-
supplied itemsMax, matching cutsceneParseDoc's convention of never
assuming ownership of the backing buffer's size.

cutscene_t.items drops its const qualifier to allow this in-place
mutation; cutsceneitem_t backing arrays in the test fixtures that get
assigned into a mutable cutscene_t.items are no longer declared const
either, since a const source would otherwise silently violate the
field's new type.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-15 13:16:02 -05:00
YourWishesandClaude Sonnet 5 dbb5301ade Extract battleactiontype_t/battleaction_t into battleaction.h
Matches the existing battleability.h/battlefighter.h split - keeps
battle.h focused on the overall battle_t state machine rather than
also owning the action data shape.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-14 12:28:40 -05:00
YourWishesandClaude Sonnet 5 74a4290be4 Add optional cutscene field to move schema
Lets a move reference a cutscene to play when used, resolved by name
the same way a CUTSCENE item's "name" field is. Still just a schema
placeholder - no loader consumes moves.jsonc yet.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-14 12:10:06 -05:00
YourWishesandClaude Sonnet 5 3ce892f846 Move items.jsonc under items/, add starter battle/moves.jsonc
Groups item data under assets/items/ to match the cutscenes/ folder
convention, updating itemInit()'s asset path accordingly. Also adds
assets/battle/moves.jsonc as a starting point for move data - there's
no JSON loader consuming it yet (battleability_t is still just a bare
enum), so its field shape is a placeholder rather than a contract.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-14 12:00:46 -05:00
YourWishesandClaude Sonnet 5 68cebce04a Remove per-item cutscene authoring macros
Every CUTSCENE_XXX(...) shorthand (CUTSCENE_WAIT, CUTSCENE_TEXT,
CUTSCENE_ENTITY_WALK_TO, etc.) existed to build a cutsceneitem_t literal
in C; real cutscenes are now authored exclusively as .jsonc files, and
the only other users were test fixtures. Deletes all ~55 of these
macros (and the shared CUTSCENE_ITEM(...) helper they built on) along
with their doc comments, leaving each item's struct/enum/Start/Update/
Load declarations untouched.

test_battle.c, test_cutscenecontrol.c, test_cutscenemaparea.c,
test_cutscenesystem.c and test_entityinteract.c now build their
cutsceneitem_t fixtures as plain struct literals instead.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-14 11:20:58 -05:00
YourWishesandClaude Sonnet 5 1646e964b5 Remove the C-authoring shorthand for declaring cutscenes
CUTSCENE(...)/CUTSCENE_REFERENCE/CUTSCENE_CUTSCENE/CUTSCENE_INSERT
existed to build a cutscene_t and its item array directly in C; real
cutscenes are now authored exclusively as .jsonc files parsed via
cutsceneParseDoc, so these are dead weight in production. Deletes the
demo scene that still used them (testcutscene.h, wired to NPC #3) along
with its now-dead include in npc.c. test_cutscenesystem.c - the only
other user, building cutscenes in-memory for tests - now writes the
equivalent struct literals directly, matching the convention already
used by test_battle.c/test_entityinteract.c.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-14 09:52:42 -05:00
YourWishesandClaude Sonnet 5 2ee97ad4ce Sunset the dedicated cutscene asset loader and the item pool
Cutscenes now load through the generic ASSET_LOADER_TYPE_JSON loader
and parse straight into fixed static buffers via new cutsceneParseDoc/
cutsceneParseItem/cutsceneCountItems helpers (cutscene.c), removing the
bespoke ASSET_LOADER_TYPE_CUTSCENE pipeline entirely. Only one cutscene
(plus one INSERT target) is ever resident, so each resolve locks,
steals the parsed doc, unlocks, and force-reaps immediately - fixing a
stale-cache-reuse bug where revisiting a cutscene name after a
different one could return data from the shared buffer's previous
occupant.

ENTITY_WALK_TO and MAP_AREA_WAIT now store their waypoints/area ids in
fixed-size arrays inline on their own item struct instead of a shared
bump-allocated pool, so pool/poolOffset are gone from every item type's
Load callback. cutscene_t.dataSize (and the CUTSCENE(...) macro's SIZE
parameter) is removed along with it - it sized entries out of that same
now-deleted pool and had no other reader.

NPC #4's battletest cutscene and the main menu's cutscene now resolve
their target by name on interact instead of eagerly at init, so a
resolved-once pointer is never held past the point its backing buffer
can be reused for something else.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-13 15:18:57 -05:00
YourWishesandClaude Sonnet 5 109ddc9e1e Switch item definitions to a JSON-driven runtime registry
Replaces the build-time item.json/tools.item.py code generator with a
single item_t ITEM registry populated at runtime by parsing
assets/items.jsonc, so items/types can grow without a rebuild. Adds
itemGetDefById/itemGetTypeById/itemGetIdByName/itemTypeGetOrCreate,
updates inventory/backpack to size off the new *_DEF_COUNT_MAX caps
and look up types dynamically, and reorders engine init so rpgInit
(which loads items) runs before uiInit (which needs the item type
count to size the backpack's tabs).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-13 11:36:50 -05:00
YourWishesandClaude Sonnet 5 804f8aa1fa Re-add CUTSCENE_INSERT item with its own dedicated load buffer
Splicing a JSON-authored INSERT target by name previously resolved
through the same shared CUTSCENE_LOADED_ITEMS/POOL buffer as whatever
outer cutscene was currently running, so loading it would clobber the
outer cutscene's own items mid-playback - that's why it was reverted.
Gives INSERT its own smaller CUTSCENE_INSERT_ITEMS/POOL buffer and lets
the cutscene asset loader be told which buffer set to parse into, so an
INSERT's dynamic load no longer stomps the running cutscene.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-13 11:12:43 -05:00
YourWishes 49b97ba508 Switch cutscene system to a set of pre deffed buffers 2026-09-13 09:58:57 -05:00
YourWishes 6c11d8165d Revert "Add CUTSCENE_INSERT item to splice another cutscene's items in place"
This reverts commit 6af0e9cf28.
2026-09-13 09:29:23 -05:00
YourWishesandClaude Sonnet 5 93554b39ba Add DUSK_TRACK_MEMORY allocation tracker and memoryCheckUnfreed report
memoryAllocate() becomes a macro capturing __FILE__/__LINE__ into a
fixed-size tracking table when DUSK_TRACK_MEMORY is enabled (Linux only
for now), so a leak surviving to shutdown can be traced back to its call
site. Replaces engineDispose's hard assertTrue with memoryCheckUnfreed(),
which reports unfreed allocations (with call sites when tracking is on,
just a count otherwise) instead of aborting.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-13 09:19:24 -05:00
YourWishesandClaude Sonnet 5 6af0e9cf28 Add CUTSCENE_INSERT item to splice another cutscene's items in place
Unlike CUTSCENE (a one-way jump that replaces the running cutscene),
INSERT splices a referenced cutscene's items into the running one and
resumes right after itself once they run out. Backed by a small return
stack on CUTSCENE_SYSTEM so inserts can nest.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-13 08:56:26 -05:00
YourWishesandClaude Sonnet 5 083deb8357 Move cutscene item type enum and authoring macros to their own headers
cutsceneitemtype_t moves from cutsceneitem.h into cutsceneitembase.h,
alongside a new CUTSCENE_ITEM(TYPE, UNION_NAME, ...) shorthand that
fills in a cutsceneitem_t literal's .type and union member together.

Every CUTSCENE_* authoring macro (CUTSCENE_WAIT, CUTSCENE_TEXT,
CUTSCENE_AUDIO_PLAY, etc.) moves out of the single, ever-growing
cutscene.h into the header of the item type it actually authors,
built on top of CUTSCENE_ITEM. cutscene.h now only holds cutscene_t
itself plus the CUTSCENE/CUTSCENE_REFERENCE/CUTSCENE_CUTSCENE macros,
which aren't tied to any one item type. Every relocated macro also
gained a proper JSDoc-style comment block with @param tags.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-12 22:30:23 -05:00
YourWishesandClaude Sonnet 5 ffb375faeb Add battle abilities and wire them into START_BATTLE cutscene parsing
Adds a battleability_t enum (starting with FIRE) and a fixed
abilities[8] array on battlefighter_t. Extends the START_BATTLE
cutscene item to parse an optional per-enemy "abilities" JSON array
(via a new cutsceneJsonLookupBattleAbility name lookup) and copies
abilities onto every spawned fighter, from the party roster for
allies and from the parsed config for enemies.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-12 22:30:12 -05:00
YourWishesandClaude Sonnet 5 b8cbd8ff6a Make party and save-slot init/new-game operate on SAVE.slot directly
party.c's functions no longer take a party_t* - they always operate on
SAVE.slot.party, since gameplay only ever has one active party. That
forced the same change on saveSlotInit/saveSlotNewGame (they called
partyInit/partyAddMember internally), so those are now parameterless
too, always resetting/seeding SAVE.slot. Callers building a save at a
specific index (new-game creation, slot deletion) now set
SAVE.slotCurrent first instead of building an independent local struct -
safe since the select-save screen is only ever reached before any
gameplay starts.

saveSlotWriteJSON/saveSlotReadJSON deliberately keep their explicit
saveslot_t* parameter - they're genuine serialization primitives used
by the save-device layer and tests against arbitrary structs, unrelated
to the single-current-party assumption. saveSlotReadJSON's internal
reset is now a plain memset instead of delegating to the now-global-only
saveSlotInit().

Updates test_save/test_savedevice/test_savedevicelinux/test_saveslot for
the new signatures. Note: test_savedevice/test_savedevicelinux/test_save
have pre-existing failures in this sandbox unrelated to this change -
savetestfixture.c swaps $HOME, but saveDeviceLinuxGetDirectory actually
derives the save path from ASSET.baseDirectory (the executable's own
location), so the fixture's sandboxing never actually applies. test_
saveslot.c (which doesn't depend on that fixture) passes 15/15.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-12 21:30:08 -05:00
YourWishesandClaude Sonnet 5 c2bd761383 Remove testbattle - superseded by the JSON-driven battle cutscene
testBattleStart() was never actually called anywhere (its only trace
was a stray unused include in uimainmenu.c) - battletest.jsonc's
START_BATTLE/REGULAR_BATTLE flow replaces it.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-12 21:14:50 -05:00
YourWishesandClaude Sonnet 5 878e3438c8 Complete REGULAR_BATTLE immediately, fix stale saveslot tests
REGULAR_BATTLE previously never completed on its own, hanging any
cutscene that reached it - START_BATTLE already waits out the whole
encounter and returns to the overworld before this item ever runs, so
it's now a completes-immediately hook point for future regular-battle-
specific follow-up.

Also updates test_saveslot.c for the mapName/partyMembers schema
additions: the round-trip test now writes a valid map name for its
in-use slot, "missingFieldsUseDefaults" is replaced with a test for the
blank-slot short-circuit it was actually hitting, and a new regression
test locks in that an in-use slot with no map name is treated as corrupt.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-12 19:59:16 -05:00
YourWishesandClaude Sonnet 5 3da65370e0 Add requireStrMin save-JSON shorthand
Replaces the hand-rolled mapName missing/null/empty check in
saveSlotVer1ReadJSON with a reusable macro.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-12 19:55:17 -05:00
YourWishesandClaude Sonnet 5 83e646cba9 Load the save's map on select, seed a real new-game slot, fix readString off-by-one
New games now go through saveSlotNewGame (starting party + default map
name) instead of the empty saveSlotInit, and selecting a save loads its
stored map instead of the hardcoded boot-time overworld. Save loading now
requires an in-use slot to have a non-empty map name, treating a blank one
as corruption instead of silently faking a default.

Also fixes a real off-by-one in the readString save-JSON macro: it passed
its maxLength (documented as excluding the null terminator) straight
through as stringCopy's destSize, which needs +1 for the terminator - so a
string exactly at the length limit (e.g. "overworld", 9 chars) always
asserted "src is too long".

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-10 23:14:44 -05:00
YourWishesandClaude Sonnet 5 0566166af4 Persist party across saves and flag/warn on corrupt save slots
Party moves off a global singleton onto each save slot, letting
START_BATTLE pick specific active-order members to bring into a fight,
and round-trips through save/load via saveslotver1. A corrupt slot load
now flags the cache and shows a red "Corrupted Save" warning in the
select-save UI instead of silently resetting.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-10 14:19:03 -05:00
YourWishesandClaude Sonnet 5 ed0b8c3911 Exit delete mode on save select after delete or back button
Previously deleting a save left the panel in delete mode, and pressing
back while in delete mode closed the whole save-select screen instead
of just returning to the normal load view.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-09 21:38:28 -05:00
YourWishesandClaude Sonnet 5 03d753a83f Move cutscene JSON parsing entirely into the async loader phase
File read, yyjson parse, and all item dispatch now happen in
assetCutsceneLoaderAsync - none of it touches the main thread now that
CUTSCENE items defer their nested asset resolution to start time. The
sync phase is now just a state flip, kept only so assetUpdate()'s
onLoaded dispatch (which only fires for entries finishing via the sync
path) still runs.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-09 21:34:47 -05:00
YourWishes cf51ed1988 Fixed cutscene item cutscene trying to recursively load 2026-09-09 21:21:50 -05:00
YourWishesandClaude Sonnet 5 70f46e89d3 Merge branch 'raw-json-maps' into main
Load map chunks from raw JSON at runtime instead of a baked DCF/DMF
step, add a reusable perf timing module, fix a real PSP logDebug/logError
Memory Stick I/O cost bug, and switch chunk tile storage to a dense
minified grid.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-09 15:34:08 -05:00
1042 changed files with 25831 additions and 27007 deletions

No files matched your search

+1 -1
View File
@@ -91,7 +91,7 @@ assets/borrowed
/archive0 /archive0
/archive1 /archive1
# /archive /archive
__pycache__ __pycache__
+17
View File
@@ -142,13 +142,30 @@ endif()
# asset edit. tools.asset.pack itself decides whether anything actually # asset edit. tools.asset.pack itself decides whether anything actually
# changed (see its manifest check) and no-ops quickly when nothing did, # changed (see its manifest check) and no-ops quickly when nothing did,
# so this stays cheap on a build where assets are untouched. # so this stays cheap on a build where assets are untouched.
#
# A .ds script under assets/ is compiled to .dsb by duskscriptcc as part of
# packing, so dusk.dsk only ever carries bytecode. duskscriptcc is a host
# tool, only built when target_system is the build host (linux/knulli, see
# src/CMakeLists.txt) - a cross-compiled console target has no duskscriptcc
# of its own to depend on or pass down, so it can only pack assets with no
# .ds in them until something sets up a host-built duskscriptcc for it too.
if(DUSK_TARGET_SYSTEM STREQUAL "linux" OR DUSK_TARGET_SYSTEM STREQUAL "knulli")
set(DUSK_ASSET_PACK_DUSKSCRIPTCC_ARGS --duskscriptcc "$<TARGET_FILE:duskscriptcc>")
set(DUSK_ASSET_PACK_DEPENDS duskscriptcc)
else()
set(DUSK_ASSET_PACK_DUSKSCRIPTCC_ARGS "")
set(DUSK_ASSET_PACK_DEPENDS "")
endif()
add_custom_target(DUSK_ASSETS_BUILT ALL add_custom_target(DUSK_ASSETS_BUILT ALL
COMMAND ${CMAKE_COMMAND} -E make_directory "${DUSK_ASSETS_DIR}" COMMAND ${CMAKE_COMMAND} -E make_directory "${DUSK_ASSETS_DIR}"
COMMAND ${Python3_EXECUTABLE} -m tools.asset.pack COMMAND ${Python3_EXECUTABLE} -m tools.asset.pack
--input "${DUSK_ASSETS_DIR}" --input "${DUSK_ASSETS_DIR}"
--output "${DUSK_ASSETS_ZIP}" --output "${DUSK_ASSETS_ZIP}"
${DUSK_ASSET_PACK_DUSKSCRIPTCC_ARGS}
WORKING_DIRECTORY "${DUSK_ROOT_DIR}" WORKING_DIRECTORY "${DUSK_ROOT_DIR}"
BYPRODUCTS "${DUSK_ASSETS_ZIP}" BYPRODUCTS "${DUSK_ASSETS_ZIP}"
DEPENDS ${DUSK_ASSET_PACK_DEPENDS}
COMMENT "Packing assets into dusk.dsk" COMMENT "Packing assets into dusk.dsk"
VERBATIM VERBATIM
) )
Binary file not shown.
Binary file not shown.
-68
View File
@@ -1,68 +0,0 @@
{
"items": [
// First thing, try and find a save device, used for settings and what not.
{
"type": "MODAL",
"title": "initial.checking_save.title",
"message": "initial.checking_save.message"
},
{
"type": "WAIT",
"seconds": 0.2
},
{
"type": "SAVE_DEVICE_CHECK",
"successMarker": "CONTINUE",
"failureMarker": "SAVE_DEVICE_NOT_FOUND"
},
// No save device found
{
"type": "MARKER",
"name": "SAVE_DEVICE_NOT_FOUND"
},
{
"type": "MODAL_CLOSE"
},
{
"type": "MODAL_OPTIONS_MARKERS",
"title": "initial.no_device.title",
"message": "initial.no_device.message",
"options": [
{
"text": "initial.no_device.retry",
"marker": "SAVE_DEVICE_RETRY"
},
{
"text": "initial.no_device.continue",
"marker": "CONTINUE"
}
]
},
// Save device not found, user to retry, just close modal and loop
{
"type": "MARKER",
"name": "SAVE_DEVICE_RETRY"
},
{
"type": "MODAL_CLOSE"
},
{
"type": "RESTART"
},
// Save device found (or continuing without one)
{
"type": "MARKER",
"name": "CONTINUE"
},
{
"type": "MODAL_CLOSE"
},
{
"type": "CUTSCENE",
"name": "main_menu"
}
]
}
-140
View File
@@ -1,140 +0,0 @@
{
"items": [
{
"type": "MARKER",
"name": "MAIN_MENU_IDLE"
},
{
"type": "UI_SHOW",
"name": "main_menu"
},
// Options button goes here - no options screen yet, so this is just
// an alias landing right back on the idle loop below.
{
"type": "MARKER",
"name": "OPTIONS"
},
{
"type": "IDLE"
},
// New Game button goes here.
{
"type": "MARKER",
"name": "NEW_GAME"
},
{
"type": "MODAL",
"title": "main_menu.checking_save.title",
"message": "main_menu.checking_save.message"
},
{
"type": "WAIT",
"seconds": 0.2
},
{
"type": "SAVE_DEVICE_CHECK",
"successMarker": "SAVE_DEVICE_FOUND",
"failureMarker": "SAVE_DEVICE_NOT_FOUND"
},
// Save device not found
{
"type": "MARKER",
"name": "SAVE_DEVICE_NOT_FOUND"
},
{
"type": "MODAL_CLOSE"
},
{
"type": "MODAL_OPTIONS_MARKERS",
"title": "main_menu.no_device.title",
"message": "main_menu.no_device.message",
"options": [
{
"text": "main_menu.no_device.retry",
"marker": "NEW_GAME"
},
{
"text": "main_menu.no_device.continue",
"marker": "SAVE_DEVICE_FOUND"
}
]
},
// Save data failed to load (e.g. corrupt/unreadable) - only option is
// to retry, no "continue without saving" here since we already know a
// device is present.
{
"type": "MARKER",
"name": "LOAD_ERROR"
},
{
"type": "MODAL_OPTIONS_MARKERS",
"title": "main_menu.save_load_error.title",
"message": "main_menu.save_load_error.message",
"options": [
{
"text": "main_menu.save_load_error.retry",
"marker": "NEW_GAME"
}
]
},
// Quit Game button goes here. Cancelling jumps back to
// MAIN_MENU_IDLE; confirming falls through to QUIT_GAME, which
// ends the process directly.
{
"type": "MARKER",
"name": "QUIT"
},
{
"type": "MODAL_OPTIONS_MARKERS",
"title": "main_menu.quit_confirm",
"options": [
{
"text": "ui.confirm.confirm",
"marker": "QUIT_CONFIRMED"
},
{
"text": "ui.confirm.cancel",
"marker": "MAIN_MENU_IDLE"
}
]
},
{
"type": "MARKER",
"name": "QUIT_CONFIRMED"
},
{
"type": "QUIT_GAME"
},
// main menu just listens for cutscene ending to show the select save modal
// so we have that here.
{
"type": "MARKER",
"name": "SAVE_DEVICE_FOUND"
},
{
"type": "MODAL_CLOSE"
},
{
"type": "SAVE_LOAD_ALL_SLOTS",
"successMarker": "LOADED",
"failureMarker": "LOAD_ERROR"
},
// Must be the very last item - falling off the end here is what
// completes the cutscene and fires uiMainMenuOpenSelectSave (see
// cutsceneSystemSetOnComplete in ui/screen/mainmenu/uimainmenu.c).
// Placing this anywhere earlier would fall through into whatever
// comes next instead (e.g. the QUIT block, if placed just before it).
{
"type": "MARKER",
"name": "LOADED"
}
]
}
+20
View File
@@ -0,0 +1,20 @@
// Entry point, run once by the engine after every other system is ready.
var camera = entityAdd();
var cameraPosition = entityAddComponent(camera, COMPONENT_TYPE_POSITION);
entityAddComponent(camera, COMPONENT_TYPE_CAMERA);
entityPositionLookAt(camera, cameraPosition, 3, 3, 3, 0, 0, 0);
var cube = entityAdd();
var cubePosition = entityAddComponent(cube, COMPONENT_TYPE_POSITION);
var cubeRenderable = entityAddComponent(cube, COMPONENT_TYPE_RENDERABLE);
entityRenderableSetMesh(cube, cubeRenderable, "cube");
entityPositionSetLocalPosition(cube, cubePosition, 0, 0, 0);
var plane = entityAdd();
var planePosition = entityAddComponent(plane, COMPONENT_TYPE_POSITION);
var planeRenderable = entityAddComponent(plane, COMPONENT_TYPE_RENDERABLE);
entityRenderableSetMesh(plane, planeRenderable, "plane");
entityPositionSetLocalPosition(plane, planePosition, 0, 0, 0);
consolePrint("Camera, cube and plane created");
+20 -1
View File
@@ -73,6 +73,12 @@ msgstr "Select Save"
msgid "ui.select_save.empty" msgid "ui.select_save.empty"
msgstr "Empty Slot" msgstr "Empty Slot"
msgid "ui.select_save.corrupt"
msgstr "Corrupted Save"
msgid "ui.select_save.corrupt_warning"
msgstr "This save file is corrupted and could not be loaded. Please contact support if this issue persists."
msgid "ui.select_save.slot_format" msgid "ui.select_save.slot_format"
msgstr "%s Lv.%d %s" msgstr "%s Lv.%d %s"
@@ -260,6 +266,10 @@ msgstr "loading"
msgid "ui.autosave.saving" msgid "ui.autosave.saving"
msgstr "SAVING" msgstr "SAVING"
#
# Items
#
msgid "item.potion.name" msgid "item.potion.name"
msgstr "Potion" msgstr "Potion"
@@ -267,4 +277,13 @@ msgid "item.potato.name"
msgstr "Potato" msgstr "Potato"
msgid "item.apple.name" msgid "item.apple.name"
msgstr "Apple" msgstr "Apple"
#
# Moves
#
msgid "move.fire.name"
msgstr "Fire"
msgid "move.slash.name"
msgstr "Slash"
@@ -1 +0,0 @@
{"meshes":[{"file":"house_4_4.dmf","pos":[2,1,0]},{"file":"house_6_3.dmf","pos":[1,9,0]},{"file":"house_2_2.dmf","pos":[12,6,0]}],"tiles":[[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0]]}
@@ -1 +0,0 @@
{"tiles":[[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[6,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[7,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[3,0],[1,1],[1,1],[1,1],[1,1],[1,1],[1,1],[5,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[3,0],[1,1],[1,1],[1,1],[1,1],[1,1],[1,1],[5,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[3,0],[1,1],[1,1],[1,1],[1,1],[1,1],[1,1],[5,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[8,0],[4,0],[4,0],[4,0],[12,0],[1,1],[1,1],[5,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[3,0],[1,1],[1,1],[5,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[3,0],[1,1],[1,1],[5,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[8,0],[4,0],[4,0],[9,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0]],"meshes":[{"file":"house_5_3.dmf","pos":[1,1,0]}],"entities":[{"type":"global","globalId":3,"pos":[8,8,1]},{"type":"item","itemId":1,"quantity":1,"pos":[12,2,0]}],"areas":[{"min":[11,3,0],"max":[16,9,10],"callbackId":1,"notify":3,"trigger":6}]}
@@ -1 +0,0 @@
{"meshes":[{"file":"house_8_4.dmf","pos":[1,1,0]},{"file":"house_3_3.dmf","pos":[11,2,0]},{"file":"house_2_2.dmf","pos":[3,11,0]}],"tiles":[[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,null,null,null,[1,0],[1,0],null,null,null,[1,0],[1,0],[1,0],null,null,null,null,null,null,null,null,[1,0],[1,0],null,null,null,[1,0],[1,0],[1,0],null,null,null,null,null,null,null,null,[1,0],[1,0],null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0]]}
@@ -1 +0,0 @@
{"meshes":[{"file":"house_3_2.dmf","pos":[1,1,0]},{"file":"house_2_3.dmf","pos":[7,2,0]},{"file":"house_4_2.dmf","pos":[1,8,0]},{"file":"house_1_1.dmf","pos":[11,10,0]},{"file":"house_5_2.dmf","pos":[13,6,0]}],"tiles":[[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,[1,0],null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0]]}
@@ -1 +0,0 @@
{"meshes":[{"file":"house_5_5.dmf","pos":[3,2,0]},{"file":"house_2_3.dmf","pos":[10,3,0]},{"file":"house_3_1.dmf","pos":[1,12,0]}],"tiles":[[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],null,null,null,[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0]]}
@@ -1 +0,0 @@
{"tiles":[[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,3],[1,3],[1,3],[1,3],[1,3],[1,3],[1,0],[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,3],[1,3],[1,3],[1,3],[1,3],[1,3],[1,0],[1,0],[1,0],[1,0],null,null,[1,0],[1,0],[1,0],[1,0],[1,3],[1,3],[1,3],[1,3],[1,3],[1,3],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[4,2],[4,2],[4,2],[4,2],[4,2],[4,2],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[4,1],[4,1],[4,1],[4,1],[4,1],[4,1],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[4,0],[4,0],[4,0],[4,0],[4,0],[4,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0]],"meshes":[]}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_1_1.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_1_2.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_1_3.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_1_4.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_1_5.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_1_6.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_1_7.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_1_8.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_2_1.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_2_2.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_2_3.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_2_4.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_2_5.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_2_6.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_2_7.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_2_8.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_3_1.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_3_2.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_3_3.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_3_4.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_3_5.dmf",
"color": [255, 0, 255, 255]
}
-4
View File
@@ -1,4 +0,0 @@
{
"mesh": "meshes/buildings/house_3_6.dmf",
"color": [255, 0, 255, 255]
}
Loaded 100 of 1042 files, more files were not shown because too many files have changed in this diff. Show more