stardance has been extended another month! the new deadline is october 31 :)

You are browsing as a guest. Sign up (or log in) to start making projects!

torkel

@torkel

Joined June 1st, 2026

  • 129Devlogs
  • 2Projects
  • 2Ships
  • 35Votes
a so called "programmer"

banner credit @lix
Open comments for this post

7h 57m 41s logged

map edit kinda overhauled

changes

map edit stuff

  • the brush size is now 1 to 8 instead of 1 to 5. size 1 is one hex, size 2 is 7, size 3 is 19, etc. Ctrl+scroll also changes the size
  • added Rect and Circle shapes alongside the brush. they work with Paint, Erase and Select. Rect uses opposite corners, Circle goes from a center out to the hex you release on. both apply on release
  • paint previews are green, erase previews are red, and selection previews are yellow. selected tiles get a blue overlay
  • added tool hotkeys: B for Paint, E for Erase and Q for Select
  • Esc cancels a drag. Rect and Circle do nothing if cancelled, while a brush stroke gets reverted instead of leaving half the changes behind
  • loading a map now prompts before discarding a dirty map, and successfully creating or loading a map clears the old undo history

selecting and editing multiple tiles

  • Select now supports click and drag, Shift+drag to add to the selection and Ctrl+drag to remove from it
  • the toolbar shows the selection count and has Clear and Delete buttons. Delete removes all selected tiles in one undo step
  • the Tile Editor can edit the type and walkability of the whole selection at once. when selected tiles differ, the controls show mixed values etc.
  • material editing only appears when every selected tile shares a type. Override Current Type changes the material for every tile using that type, while Save as New Type assigns a matching type to the selection without changing every other tile using the old type
  • brush strokes, Rect/Circle fills, deletes and bulk type or walkability changes are each grouped into one undo step. changing a type’s material itself is still not undoable….

the console….

  • logging now has a sink system, so the same formatted log messages can go to different outputs
  • the editor now has separate Logs and ObSL panels. engine/application logs go to Logs now, and script stdout goes to ObSL
  • the panels have Clear and Copy buttons and keep the latest 2000 lines. the UI sink buffers incoming logs under a mutex before the editor consumes them

closing the editor

  • closing the window now goes through a callback, so unsaved scene or project changes trigger the save/discard prompt instead of immediately closing
  • removed the old global Esc-to-quit shortcut.
  • ObSL’s CloseWindow() no longer closes the editor while in Editor mode. it logs that it was called instead. in the runtime, it still closes the window

windows and smaller fixes

  • enabled /MP for MSVC builds, and the editor/runtime targets use the Windows GUI subsystem so they don’t launch with a console window attached
  • atomic file writes now write the byte buffer explicitly and retry Windows file replacement when it fails with access-denied or sharing-violation errors, for up to about 2 seconds
  • a bit of cleanup around collision pair sorting, const-correctness and naming

docs

updated the editor guide and screenshot to cover the new tools, shapes, selection controls, shortcuts and undo behavior. blah blah


…map editing is finally a lot less barebones…

0
0
18
Open comments for this post

3h 1m 11s logged

uhhh

changes

dont nuke scene on failed load

  • scene deserialization moved out of Scene::OnEnter into SceneManager::LoadScene, and now runs before the old scene gets torn down. if the new one fails, you stay in the old scene (LoadSceneByPath returns a bool now)
  • loading is stricter. missing map files, bad/out-of-range/cyclic parent values and broken UI sections fail the load instead of logging an error and limping on
  • persistent entity migration happens before the swap too, so a failed asset acquire can’t leave you half in the new scene
  • the editor’s LoadScene used to clear the current project before trying to load. now undo history and selection only get cleared once the load actually worked
  • saving: map write failures now propagate instead of reporting success, and files get closed before the error check

destroying entities

  • DestroyEntity was recursive, now it’s iterative with a visited set. deep hierarchies, cycles and duplicate child entries no longer kaboom the stack or double delete, and children go first (wow that sounds dark)
  • Reparent and SetParentDirect go through CanSetParent, which rejects cycles and stale parents, even if the existing hierarchy is already cyclic
  • script DestroyEntity / entity.Destroy() now use RequestDestroy to tag the entity and its whole subtree instead of deleting immediately, so on_destroy runs before deletion. scene exit drains the destroy queue too, including entities tagged by exit hooks
  • the script wrapper cache evicts an entity when it’s destroyed
  • a dumb one…: the hot-reload cleanup list had on_exit in it twice and no on_destroy, so on_destroy GC roots never got released …
  • the script system was holding raw ScriptComponent* across initialization, which dangles if a script spawns enough entities to grow the pool. it looks components up by entity ID now
  • script runtime reinitialization after a scene change uses the VFS path and reruns setup, so using imports keep working from the mounted project

ui undo

UI elements have UUIDs now, and undo commands resolve them by UUID instead of holding raw pointers. removing an element captures the whole subtree plus its sibling position, so undo restores the hierarchy and order. renaming also updates the name index live.

smaller fixes

  • collision broadphase is a “spatial hash grid” now instead of checking every pair
  • lightmap rebakes when ambient changes, and handles maps with no tiles
  • atomic file writes use unique temp names so concurrent writers don’t trip over each other
  • project changes wait for background asset loads to finish
  • timeout timers are mutex-protected, and callbacks can schedule more timers without deadlocking
  • SmallTask over-aligned captures fall back to the heap
  • VFS::Resolve("..") had UB from a std::mismatch that wasn’t bounded on the second range…
  • PlayMusic stops, swaps and starts under the lock now instead of racing!!!

tests

wrote a pile of tests alongside all this: atomic writes, wrapper cache, hierarchy safety, map serialization, save concurrency, scene loading failures, script lifecycle, script modules, SmallTask and timeouts. expanded to the editor command, save game and VFS tests.


so EVEN LESS explosions !!! Woo!

0
0
45
Open comments for this post

4h 44m 1s logged

undo stuff + render lifetime fixes

undo / redo

the undo system relied way too much on runtime entity IDs and direct pointers into components.

that works until an entity gets deleted, an ECS slot gets recycled, or a dense component pool moves stuff around…

entity commands now store the entity UUID and resolve the current runtime entity when they execute / undo instead.

this now applies to transforms, renaming, adding / removing components, script changes, component field edits and map painting.

so older commands can still find the right entity even if it was deleted and later restored with a completely different runtime ID.

deleting things is actually undoable now

finally added proper undo for deleting entities. !!!!!!

deleting an entity snapshots the whole subtree first, including components, UUIDs, names, hierarchy + sibling order, scripts, custom data and asset references.

undo rebuilds the tree, reloads required assets, restores the UUIDs and puts everything back where it was.

this also means edits from before the deletion still work afterwards, since those commands just resolve the restored entity by UUID.

paste uses the same snapshot system now too, so undo / redo keeps the same pasted entity identities instead of creating unrelated ones every time.

there are checks for conflicting UUIDs, missing parents, invalid hierarchies, missing assets etc. failed restores shouldn’t leave half-created entities behind.

failed commands also no longer get added to undo history or wipe an existing redo chain.

custom ObSL data

custom script data needed special handling too.

arrays / objects can share references or even be cyclic, so just copying ObSL::Values wasn’t enough.

there’s now a snapshot format that captures the object graph and rebuilds it through the interpreter + GC when an entity is restored.

CustomDataComponent also roots stored ObSL values properly so GC-managed objects stay alive.

runtime functions aren’t snapshotable though, so deletion just fails instead of restoring garbage.

render thread lifetime stuff

also did a pretty big pass over renderer resource lifetime, mostly because scene switching could unload resources while an already submitted frame was still using them.

(this started because someone mightve pointed out a lil crash for me…)

render commands now pin the meshes, materials, shaders and textures they need until that frame is done.

same idea for UI textures and the editor viewport framebuffer.

OpenGL objects also don’t call glDelete* from whichever thread destroys the C++ object anymore. textures, shaders, buffers, VAOs and framebuffers queue deletion for the render thread, while it actually owns the GL context.

less bugs yay

frame state + shutdown

renderer state that can change while the render thread is behind is captured per frame now too, including clear color, post-processing and UI resolution / projection state.

shutdown is also more deliberate now: worker threads stop first, background font loads finish, scripts stop, scenes/resources are cleared, renderer/UI resources shut down, then the remaining GL delete queue is processed while a context still exists.

font loading uses tracked jthreads now too instead of detached threads.

small things

exporting now reports success / failure back to the editor and shows a little result popup instead of silently relying on the console.

also added tests around delete / restore, UUID reuse, hierarchy restoration, script components, map edits, pasting, command failures and repeated undo / redo without leaking entities or asset references.


so. .. . less explosions hopefully

sorry if wording is weird.. character limit..

0
0
17
Open comments for this post

3h 15m 28s logged

export dependencies + prefab asset loading

redid how exporting figures out what needs to go into the package

previously editor export was basically much closer to just packing the project directory. now it builds a dependency manifest first

figuring out what to export

export starts from the project + scenes and follows the things they reference:

  • catalog assets used by entities, maps, UI and post processing
  • map files
  • attached ObSL scripts
  • script using imports
  • scenes loaded from scripts
  • prefabs instantiated from scripts
  • music / sound files
  • material textures + shaders
  • animation sheets
  • shader #includes

referenced scenes and prefabs get scanned too, dependencies keep chaining from there.

it then generates a new filtered assets.json specifically for the package instead of sticking the entire project catalog in there.

the actual project’s catalog is untouched.

script analysis

added a ScriptAssetAnalyzer which walks the ObSL AST without actually running anything.

literal stuff can be narrowed down properly, including things like:

PlayMusic("assets/audio/music.ogg", 1.0)

or even constant string concatenation…

asset setters like SetTexture / SetFont get tracked too.

if a texture or font ID is dynamic, export keeps that entire asset category.
if a runtime file path for stuff like LoadScene, Instantiate, PlayMusic or PlaySound2D can’t be figured out, it falls back to keeping the eligible project files + full asset catalog.
unknown / indirect calls are done the same too

so simple projects get smaller exports, while weird dynamic scripting should still work…

.pakignore still applies, and required files being missing or ignored is now an export error

prefab assets

also fixed prefabs properly interacting with the lazy asset system.

instantiating a prefab now scans its components, acquires whatever catalog assets it needs, resolves their dependencies, and retains them in the scene before creating the entity.

so a prefab can use an asset that wasn’t already referenced by the scene and it should just work.

scene asset scopes got changed a bit for this too. instead of accumulating a new scope every time something acquires assets, they’re merged into one scene scope and duplicate asset references are ignored.

also made prefab revert a little safer so the old entity isn’t destroyed unless the replacement prefab actually instantiated successfully.

packaging / ci things

editor packaging is stricter in general now. script dependency validation can fail the export, missing dependencies stop it, and PackageCurrentProject reports failure so the rest of the export doesn’t continue pretending everything is fine.

shader includes are followed during dependency collection too, while the engine shader helpers still get bundled for runtime includes.

also cleaned up CI a decent bit…

also some more tests too for the packaging and script analysis

lowk sorry for just posting an image of the logs idk how else to show it since it’s mostly backend / file stuff 😭

0
0
43
Open comments for this post

3h 37m 12s logged

more tests (more bugs)

kept going with the unit tests

the test suite now covers most of the important stuff, including:

  • ECS / entity IDs / UUIDs
  • serialization + hierarchies
  • collision geometry, events and movement
  • maps
  • animation
  • saves
  • ObSL + some EngineLib bindings
  • assets / asset lifetime
  • VFS + packaged projects
  • configuration
  • editor undo commands

also added a couple integration tests for audio and rendering (OpenGL tests are optional)

finding things

unsurprisingly this found some actual problems too.

stale entity handles can no longer remove / access components from an entity that reused the same slot, and editor undo commands are a bit safer around entities or components disappearing.

also fixed some hierarchy rotation decomposition weirdness, cleaned up VFS / package mounting state so old package data can’t leak into the next mount, and added a few other small null / cleanup checks around scenes and rendering resources.

0
0
18
Open comments for this post

3h 6m 57s logged

unit tests (& some fixes)

uhhhh started adding actual unit tests… i was kinda putting it off but i gotta have it…

set up GoogleTest + CTest and started covering some stuff

  • ECS registry / generational IDs
  • entity UUIDs
  • entity serialization
  • hierarchy / parenting
  • collision events + movement blocking
  • save games
  • maps

bugs bugs bugs…

and unsurprisingly, writing tests immediately started exposing some smaller issues.

fixed stale entity handles being able to mess with components belonging to a recycled entity slot, and cleaned up some hierarchy transform / rotation handling that wasn’t preserving transforms correctly in certain parenting cases.

also tightened up a couple math helpers while testing them.

im still gonna write even more tests.. its very needed at this point and will prolly help me find some more bugs i missed before…

0
0
51
Open comments for this post

5h 28m 46s logged

uuids, collision layers, save settings, and other stuff

bit of a mixed bag this time. mostly cleaning up some systems that were already there and filling in stuff I’d need…

entity UUIDs

entities have proper UUIDs now, separate from their normal runtime entity IDs.

the regular generational ID still does all the normal ECS stuff, while the UUID is a stable identity that gets serialized with the entity.

this mostly fixes how persistent entities work between scenes.

previously I was deduplicating persistent entities by name, which was obviously not ideal since names aren’t actually identities.

persistent entities + their children now keep their UUIDs when moving between scenes, and if the destination already has an entity with the same UUID it gets replaced by the carried-over one.

two things can have the exact same name now without persistence randomly deciding they’re the same thing.

normal prefab instances / newly created entities still get new UUIDs.

collision layers

colliders now have proper layers + masks.

there are 32 collision layers, and every collider has:

  • a layer
  • a 32-bit mask of layers it accepts

both colliders have to accept each other’s layer for the pair to interact.

the same filtering is used for normal overlap events and movement blocking, so there isn’t a separate set of collision rules depending on which system happens to be asking.

added editor controls for this too, including the layer selector, all 32 mask toggles, and select all / deselect all buttons because clicking 32 checkboxes individually sounds incredibly fun.

scripts can also read / change the layer and mask now.

collision-aware script movement

also added Transform.TryMoveTo(x, y, z) to ObSL.

unlike SetPosition, this checks whether the entity can actually occupy the destination before moving it.

the normal hex movement system uses the same helper now too, so script-controlled collision-aware movement and normal movement go through the same path.

direct SetPosition is still basically teleporting, which is intentional.

also fixed on_collision_stay actually looking up the collision stay callback instead of the trigger stay callback.

whoops.

more save settings

did some more work around the save system from the last update.

saving can now be enabled / disabled per project, and projects can choose where save files go:

  • Data Home, the normal OS application-data location
  • Portable, relative to the executable

both still use the project UUID underneath so different projects don’t start sharing save files because somebody named both of them game.

these are editable from Project Settings now.

also added a confirmation dialog when regenerating the project UUID since doing that changes which save directory the project looks at. the old saves aren’t deleted, the project just gets a new identity and stops finding them automatically.

graphics config stuff

changed packaged builds so graphics.json can live beside the executable and override the version inside the package. (i.e if someone decides to unignore the graphics config and package it)

couple random fixes

particle emitters now keep their actual live particle count, so GetAliveCount() in ObSL finally returns the real value instead of the completely useless placeholder it had before.

fixed a prefab revert issue where the code was reading the prefab path from the component after destroying the entity. very intelligent.

also made theme font loading a bit less fragile. missing / broken font files get logged and skipped instead of potentially taking the whole theme load down with them, plus some parsing cleanup.

and updated another mountain of docs to match all the collision, persistence, save, prefab, post-processing and export changes.

0
0
129
Open comments for this post

7h 2m 59s logged

save system

i wanted this to be pretty generic instead of the engine having some hardcoded idea of what a “player save” or whatever is, so the actual save data is ba sically just key/value storage that scripts can use for whatever they want!!!

save data

there’s now a SaveGameManager which keeps one active save in memory.

save values can currently be:

  • booleans
  • numbers
  • strings

the file format is versioned and also stores a display name + created / updated timestamps.

the actual save data itself doesn’t really care what the values mean. it is any key value pair that persists.

there’s also locking around the active save since scripts can be running across multiple workers…..

project UUIDs

projects also have their own UUID now.

it’s generated when the project is created or when a project that does not already have one is opened
right now it’s mainly used to give each project its own save-data directory without name collisions but im sure its good to have outside that!!!

save files

the basic save file operations too

  • create a new save
  • write the current active save
  • load a save
  • delete a save
  • list existing saves
  • start a fresh unsaved “game”

save filenames are generated from timestamps. the human-readable name stays inside the file, display names don’t need to also be valid / unique filenames.

save_list() also gives creation + update timestamps, and saves are sorted by most recently updated.

writes are atomic too, so it writes through a temporary file before replacing the real save instead of directly nuking the existing one and hoping for the best

per-project save directories

save data is stored outside the project itself in the normal OS application data home

each project gets its own directory based on its UUID

<data home>/obliberry/<project uuid>/saves/

projects with the same name don’t fight over the same saves.. (i have several projects just called “UntitledProject” lol)

this is LocalAppData on Windows, Application Support on macOS, and XDG_DATA_HOME / ~/.local/share on Linux.

both the editor and runtime configure the save manager when the project is loaded, and it gets reset again when the editor closes the project !

ObSL

ObSL savedata enginelib intergration:

basic data stuff:

  • save_set(key, value)
  • save_get(key)
  • save_has(key)
  • save_remove(key)
  • save_clear()
  • save_new()

save file management:

  • save_create(name)
  • save_write()
  • save_load(filename)
  • save_delete(filename)
  • save_list()

save_list() returns an array with the filename, display name, creation time and last update time

some cleanup

also pulled the atomic file writing stuff into a shared OS file utility, so assets.json can use the same code instead of having its own implementation.

bunch of formatting stuff too


i still have to document this and do some more testingf but yeahhh

2
0
99
Open comments for this post

6h 26m 42s logged

asset system refactor + some editor stuff

been wanting to redo how assets work for a while now.

until now scenes carried the asset definitions with them, and loading scenes would keep throwing resources into the global resource manager. worked fine enough , but it also meant resources could kinda just accumulate forever..

i seperated them now!!

assets.json

projects now have a project-wide assets.json catalog.

textures, shaders, meshes, materials, fonts, animation sets, etc. live there instead of getting serialized into every single scene.

scenes / prefabs / UI / animations etc. just store resource IDs and the definitions live in one place

besides making scene files considerably less bloated, this means saving a scene no longer serializes whatever random collection of resources happens to currently exist in the resource manager

lazy asset loading

having one project-wide catalog does not mean loading the entire project into memory.

scene loading now scans for the resources that scene actually references and loads those from the catalog

this includes stuff referenced by:

  • entities
  • maps / tile types
  • UI
  • post processing
  • spritesheets / animators

dependencies get resolved too

so if something needs a material, its shader + texture get pulled in first. animation sets pull in their spritesheet texture, etc. etc.

now the the resource manager should only contain what is actually being used

asset lifetime stuff

added SceneAssetScope for keeping track of what assets a scene has acquired.

assets are retained while something needs them and can actually be unloaded once the last scope using them disappears

so changing scenes repeatedly should no longer turn the resource manager into

yummy more objects :O

forever….

persistent entities reacquire the resources they need when moving between scenes too.

there’s also handling for catalog entries being replaced / deleted while their old resource is still loaded. those can be marked stale and discarded safely once the old scene lets go of them instead of leaving weird zombie resources around.

engine assets still stay around like normal.

editor asset workflow

the editor now goes through the asset catalog too.

creating / importing / replacing / deleting things like:

  • textures
  • shaders
  • meshes
  • materials
  • fonts
  • animation sets

updates assets.json instead of depending on scene serialization to preserve them….

supported editor selections / script setters can also acquire catalog assets on demand and attach them to the current scene’s asset scope

old projects

old projects obviously still have all their assets embedded inside their scene files, so I added an ob_asset_migrator tool.

it can scan the old scenes and merge all of those definitions into a project-level assets.json.

there’s:

  • dry-run validation
  • conflict detection
  • optional removal of the old scene assets sections
  • backups before it starts rewriting stuff

uses backups because i dont trust myself enough .. might vaporize projects who knows…

docs docs docs

also updated a stupid amount of documentation for the new asset model … since of course..

there’s now a full assets.json format page covering the different asset types, dependencies, lazy loading, asset scopes, editor behavior and migration.

updated the scene / prefab / animation / post-processing docs too since all of those previously described assets as being stored directly in scenes.

also cleaned up the main README + docs index a bit and updated the feature list because quite a lot of it was outdated at this point….

theme presets

also did some work on editor themes.

split the built-in theme definitions out and added some interesting presets:

  • Obliberry Dark
  • ImGui Classic Dark
  • Obliberry Light

ew imagine using light themes…

  • High Contrast Dark
  • Haxxorman Green

editable and all…

tldr: resourcemanager is now longer an infintly growing landfill…

1
1
45
Open comments for this post

3h 18m 8s logged

animation editor

continued working on the animation system and made the editor UI….

animation editor

there’s now a Sprite Animation Editor

you can:

  • choose the spritesheet texture
  • edit rows / columns / spacing
  • create, rename and delete clips
  • toggle looping per clip
  • edit individual frame indices + durations
  • move frames up / down
  • duplicate / remove frames
  • expand / collapse the frame list

also added range generation so adding a normal animation doesn’t make you manually enter every frame one by one…..

theres also an Apply FPS to All Frames button !

preview

added a live preview for the selected clip.

you can play, pause and restart it woaw

it shows the current clip frame and spritesheet index while it runs….

project browser integration

animation assets are properly integrated into the project browser now too

there’s an Animations section where you can create, import, edit and delete animation assets

creating a new one lets you choose its path then opens it in the animation editor.

the animation asset workflow is mostly usable from inside the editor :D

erm even more

enginelib changes for the new systen that i still have to document…
(Play() Restart() etc)

some cleanup

working on… some mostly const-correctness, explicit casts, ranges, include cleanup and some other small stuff etc etc.. god bless resharper c++

also cleaned up some EngineLib entity wrapper code around registry locking so it can create wrappers safely when the registry mutex is already held


spritesheet used in video attached for testing is : https://opengameart.org/content/animated-butterfly

0
0
80
Open comments for this post

6h 19m 27s logged

btw pls star on girhub :cute:

animation clips / refactoring spritesheets

…kinda refactoring the whole spritesheet animation thing already

the first version worked, but having FPS / looping / frame ranges etc directly on the SpriteSheetComponent was gonna get pretty limiting cuz what if I wanted multiple animations for one sprite.

it might sound stupid but for me it’s always worked to get a prototype working, then refactor/reimplement it. thats even what i did for this entire project early on, before it deleoped into a full on engine :D

so now the spritesheet is mostly just the sheet + currently displayed frame, and animation playback is seperate

animation clips

working on proper animation sets + clips.

an animation asset can have one spritesheet and multiple named clips, with each clip containing its own list of frames :D

each frame also has its own duration now instead of the whole animation just sharing one FPS value, so stuff like holding a frame longer or doing irregular timing is possible without

clips can loop independently too

animator component

added a separate SpriteAnimatorComponent which handles the actual playback state:

  • animation asset
  • initial clip
  • autoplay
  • current clip
  • current frame inside that clip
  • elapsed time
  • playing state

the normal SpriteSheetComponent is way simpler now…
it just says what sheet + frame should currently be rendered
(the animator updates that for it)

animation assets

animation sets are assets now under assets/animations/

they serialize separately and contain the spritesheet setup plus all the clips / frames / durations

they are loaded through the normal asset system and registered in the ResourceManager

scene serialization now keeps the animator config like the selected animation asset, initial clip, and autoplay

editor stuff

the sprite sheet inspector got reworked for the current thing but whole UI stuff isnt finished

once an animator is attached it owns the sheet/frame instead of both systems trying to edit the same thing.

I still need a proper UI for actually making / editing animation assets and clips though. i shall work on this next!!!

(right now the backend is pretty much all ive done but its taken a lil longer than i thought…
who wouldve thought adding cips cleanly would take this whole aah refactor)

scripting

EngineLib updates too

SpriteAnimator in scripts can now do:

  • Play("walk")
  • Restart("walk")
  • Pause()
  • Resume()
  • Stop()
  • IsPlaying()
  • GetClip()

it is now based on named clips

so i guess not anything flashy to show but… its stuff :)

0
0
131
Open comments for this post

4h 12m 52s logged

spritesheets / animation

finally … spritesheet support

spritesheets

added a new SpriteSheetComponent with:

  • texture
  • rows / columns
  • optional row + column spacing
  • start frame
  • animation length
  • FPS
  • looping
  • playing / paused state
  • current frame

basically the renderer can now render only a specific UV region of a texture

animation

also added a small sprite animation system that advances frames based on FPS and handles looping / stopping at the end etc etc

animations also update while in the editor… might be annoying for some, might be less annoying for others.. but thats how i like it

editor stuff

you can pick the texture, set rows / columns and spacing, choose the start frame + animation length, change FPS, toggle looping / playback, scrub the current frame, restart the animation, etc. etc

EngineLib

scripts can inspect stuff like the current frame, frame count, FPS, rows / columns and texture, and can also change the texture/grid/animation, set frames, play, pause, restart and stop animations.

Collider also has a proper EngineLib component wrapper instead of collision only being accessible through the callback hooks. right now that’s just getting / setting whether it’s a trigger, but it’s there.

also added both Collider and SpriteSheet to the normal GetComponent, AddComponent, RemoveComponent, HasComponent, etc. obviously.

some cleanup

did a bit of registry / EngineLib locking cleanup while I was in there too, mostly around entity wrappers being created while the registry lock is already held.

also fixed one very stupid collision callback typo where on_collision_stay was looking up the wrong hook… oops…..

im also starting on documenting this stuff…. yep.. pain…

spritesheet used in video attached for testing is : https://opengameart.org/content/animated-butterfly

0
0
194
Open comments for this post

2h 10m 35s logged

collision callbacks

scripts can do collision things now….!!!

script collision callbacks

ObSL scripts can now define collision hooks:

  • on_collision_enter(other)
  • on_collision_stay(other)
  • on_collision_exit(other)
  • on_trigger_enter(other)
  • on_trigger_stay(other)
  • on_trigger_exit(other)

the other argument is a normal EngineLib entity wrapper, scripts can do stuff like check its name, components, etc.

collision events get collected by the CollisionWorld, then dispatched to the relevant script instances afterwards. they’re also run through the existing script command buffer ofc

2D collider shapes are back too…

added explicit 2D shapes alongside the 3D ones:

  • Rectangle
  • Circle

so the full set is now:

  • Box
  • Sphere
  • Cylinder
  • Rectangle
  • Circle

rectangle / circle are flat shapes. which is nicer for sprites and other 2d things

movement actually respects colliders

hex movement now checks whether an entity can actually occupy its next tile before moving there.

added a CanOccupy() collision query which builds the entity’s collider at the target position, it blocks the move if something solid is in the way.

triggers don’t block movement.

collision robustness stuff

also did a bunch of smaller fixes around the collision

  • added a shared collision tolerance instead of random 1e-6s in different places
  • AABB overlap now uses that tolerance too
  • improved collider validation depending on the actual shape
  • fixed gizmo world-to-local conversion to use the proper inverse transform
  • more finite-value / clipping checks in the collider gizmo
  • GJK Indeterminate results preserve the previous collision state instead of automatically counting as a collision

p.s, heres a lil photo of my attempt at making syntax highlighting for obsl using textmate grammar… :D

0
0
41
Open comments for this post

3h 3m 39s logged

collision system round 2 i guess

ended up pretty much reworking most of the collision system…..

the first version was still basically 2D, with separate box vs box / circle vs circle / box vs circle functions. that worked as a starting point, but it was gonna get annoying …

so… it is 3D now.

colliders

ColliderComponent now supports:

  • boxes
  • spheres
  • cylinders
  • 3D offsets / dimensions
  • triggers
  • entity-space or billboard orientation

billboard colliders follow the same camera-facing basis as billboard rendering, which means billboard sprites can still have colliders that actually line up with how they appear on screen.

GJK

got rid of all the individual boxVBox, boxVCircle, etc. collision functions and replaced them with support-mapped collision detection using GJK.

each collider shape just provides a support point now, the intersection test doesn’t care what combination of shapes it’s checking.

i dont fully understand the math completely yet.. but it kinda makes sense :D

still no collision response / physics yet. this is just detection + events, i think ill prolly get it into EngineLib.. soon…

events

the CollisionWorld still tracks collisions between frames and generates:

  • Enter
  • Stay
  • Exit

trigger state is kept with the collision too.

this is for EngineLib integration.
scripts should be able to react to collisions / triggers like unity

I have not gotten around to this yet though…

collider gizmos

also had to redo the collider gizmos now that colliders aren’t just flat 2D shapes anymore…
its a lil janky
but it works..

billboard cleanup

while doing the billboard collider stuff I also cleaned up billboard rendering a bit

billboards used to have their world transform temporarily modified by SpriteBillboardSystem before rendering. now the billboard matrix is generated when the entity is submitted to the renderer instead, so the actual ECS transform can stay as the real entity transform

there’s now one shared billboard matrix helper used by both rendering and collision, which is considerably less cursed.


um
scripting integration next i guess.. if something dosent explode ! :D

0
0
61
Open comments for this post

3h 25m 25s logged

collision stuff

been working on a collider system.
still pretty early and not hooked into EngineLib yet, but most of the basic backend + editor stuff is there

planning to expose it to scripts in a similar way to how Unity handles collision callbacks / triggers, but that’s for later…….

collision

added a new ColliderComponent with:

  • box and circle colliders
  • offsets
  • size / radius
  • trigger support

collision system currently handles:

  • box vs box
  • circle vs circle
  • box vs circle
  • collision normals + penetration depth
  • ‘trigger’ collisions

also added a CollisionWorld that keeps track of collisions between frames and generates Enter, Stay, and Exit events. mostly groundwork for when I hook this into EngineLib…

collider editing

colliders are editable from the editor

theres a collider inspector widget for changing the shape, offset, size/radius, and whether it’s a trigger, plus a viewport gizmo for directly moving and resizing them

collider edits also go through the undo system, because every new editor feature needs to become an undo/redo problem eventually……… :D

other editor fixes

  • entity copy/paste now copies the whole child hierarchy instead of only the selected entity
  • pasted hierarchies keep their parent relationships
  • added copy/paste to the entity and UI context menus
  • fixed stale entity / UI selections after the thing being selected gets deleted
  • fixed single-key shortcuts like V, T, R, etc. firing while Ctrl/Alt/Shift was held
  • keyboard camera movement no longer fights with Ctrl/Alt shortcuts
  • a few smaller include / cleanup things

mostly collision work though. next step is probably getting the collision events into EngineLib and experimentiung w. it

its still a bit jank of course but it works i guess :DDDDD

0
0
47
Open comments for this post

4h 51m 4s logged

copy paste (kinda)

also too much time fighting windows builds

tried to get entity copy/paste working and it’s… janky.

also ended up wasting a stupid amount of time just getting windows builds to actually build again because i lowk forgot again about how it wont let me pass paths as strings implictly as it does on every other damn os…

changes

copy/paste (wip, kinda broken)

  • started on ctrl+c/ctrl+v for entities & ui in the editor it kinda works but is really janky and does not feel good to use, also tried implementing it in the context menu but its not workiong at all -.-

other

  • the windows fixes….

  • some resharper reccomendation inspection type shi

but lowk its been a while since i logged soo yep

0
0
43
Open comments for this post

3h 53m 18s logged

sllight hub overhaul

redid the project hub screen and added recent projects tracking, since up to now opening anything meant going through a file dialog every single time…

changes

  • recent projects get tracked in a PROJECTHIST file (next to the editor executable) …dead simple format, one filepath per line, each pointing at a project’s .json. capped at 5 entries, oldest just get removed off the list.
  • hub screen is basically remade two docked panels now instead of one. left panel is the same buttons as before (new project, open project, etc), right panel is the new recent-projects list, up to 5 entries since that’s all the history file holds.

also

  • removed some unused dead code i found…

QoL type stuff i guess :D

2
0
123
Open comments for this post

3h 56m 30s logged

too many post proc fx?

followup to the post processing / shader experiments…

changes

shader includes

shaders can #include "rand.glsl" etc and it resolves properly. it checks the project VFS first, then falls back to the engine’s own shader helper directory if it isn’t found there.

engine shader helpers also get packaged into exported games under engine/shaders/, so includes keep working at runtime.

added a few helper include files:

  • rand.glsl / auto_rand.glsl - seeded hash-based random, with auto_rand reseeding per frame from u_Time
  • color.glsl - HSV conversion, lift/gamma/gain, contrast, saturation, and three-way color wheels
  • commons.glsl - engine-provided uniform declarations so you don’t have to redeclareu_Resolution, etc. in every shader for engine-provided uniforms

the helpers use #ifndef / #define guards, so auto_rand.glsl can include rand.glsl without causing double declarations if the effect shader or another include declare the same uniforms or includes.

more built-in effects

added a few more built-in post processing effects:

  • ColorGrading - exposure, contrast + pivot, saturation, lift/gamma/gain, and shadow/midtone/highlight color wheels using color.glsl
  • FilmGrain - chunky per-cell grain with u_GrainSize controlling the cell size
  • Vingette - yes i know its mispelled.

uniforms with Wheel in the name now get the wheel-style color picker instead of the regular color picker, since a normal RGB slider

cleaned up effect registration

used to have two separate lists, one for raw shader registration and one for the default effect chain. this meant adding an effect involved touching two different structs in two different places.

merged those into one PPRegistration list with an inDefaultChain flag

shader debug name

added an actual m_DebugName field and made error messages / the material inspector fall back to it when there isn’t a real file path.

docs

wrote up some post-processing editor docs ….. i hate writing docs..

also

  • .shader is now a valid extension for importing custom effect shaders, alongside .frag / .glsl
  • trimmed down the miniaudio CMake config by disabling its examples, tests, and tools, along with Vorbis/Opus/FLAC support since i’m not using any of that….
0
0
43
Open comments for this post

3h 1m 2s logged

shader preprocessing

been working on a small shader preprocessor thing while also finishing up the final bits of post-processing

right now the preprocessor is pretty simple, mostly just adding support for:

  • #include
  • #pragma once

I haven’t actually needed it yet, I just kinda had the urge to make it… so now I have a shader preprocessor …?

its pretty extendable and all though so usefull to have ig :)

0
0
85
Loading more…

Followers

Loading…