Results 1 to 10 of 48

Thread: Cheb's project will be here.

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #25
    I am currently amidst an immense re-haul that changes the very architecture. Hopefully by the end of this year (2023) it would be over and I could move on with creating my first game.

    Previously:
    My "killer feature", as envisioned back in 2005, was what has since shrunk to "developer mode": all relevant code resides in a DLL that could be re-compiled and re-loaded without re-starting the engine and re-loading assets.

    I invested about 4 years total into my database engine 2006-2008 and the asset management (2012-2013) that linked game code with assets stored in the "mother executable".

    The common parts of architecture that will remain as is:
    - the mother executable has an API - a monolithic record of fields and functions in procedural variables serving the game code's gateway into the engine. Includes configs, window manager, and a dual-layer wrapper allowing the DLL using mother executable's streams as a TStream of its own.
    - the database works on "save a snapshot to TStream" principle, with perfect reproduction of the logic on load.
    - assets are identified by an unique hash (was 256 bits, reduced to 12, either randomly generated or a md5 of file name.

    The old architecture:
    the DLL had a logic thread for the object database (single-threaded by design) with assets being classes of it. The DLL managed background tasks, the logic classes had access to graphical API (OpenGL/GL ES) and had methods for rendering in the main thread. Locking was employed to prevent database from crashing while the render routine was executing an a thread not of its own. On unloading, all assets were counted and packed into a separate mother stream, which for the mother executable was a banal TMemoryStream. On loading, logic had to retrieve that list (which could be empty, if it was the first start, or containing mismatching assets from a different run, in case of switching the session). Each asset object then had to employ convoluted algorithm of devouring its stored counterpart, absorbing properties and OpenGL handles or discarding them. Which, in case of hierarchical multi-part assets like FBOs, was turning into a nightmare.

    It's no surprise that me development stalled and my phtagn asset manager was plagued by bugs very hard to catch (as everything was split into inter-dependent tasks running in background threads).

    The new architecture (I'm cutting and cutting it down):
    - it's not 2005 anymore, I am developing from a SSD.
    - no more "universal" mother that can run any of the games/tools. There is one mother executable per each game/tool (one release, one debug with assertions on).
    - the DLL is only used in the "developer mode" only available for x86 Win32. The normal mode of operation, and all other platforms, is logic built in into the main executable. No more agony of building DLLs for Linux.
    - the DLL runs in the logic thread created by the mother and that's all. The DLL never uses any other threads.
    - my new rendering architecture Kakan: the logic fills a command list in its logic thread, abstracted from any APIs, then passes it for execution and forgets it. The rendering in the main thread is done by Kakan. The logic loses all access to OpenGL.
    - assets are mother executable's classes, accessible to the logic as untyped pointers. Any specific details are exposed via pointers to T<XXX>Innards records shared between the mother and the DLL. Mother API's ExposeInnards method returns an untyped pointer. The logic's job is to type-cast it to correct P<XXX>Innards. Ugly, but I saw no other way to make it simple enough.
    - logic has its own classes for linking to assets, derived from TAbstractAssetLink. All begin with a pair (pointer + hash), where pointer (Mother's asset class instance) is never saved with the snapshot, always nil after de-serialization, and hash duplicates mother asset class's hash.
    - mother manages assets *and* their lifetime, organized in a specialized fcl-stl map addressed by hashes. Assets are reference-counted, all refcounts are reset to zero after the logic unloads.
    - most assets' actualization is handled by the mother in the render phase, employing background tasks if necessary.
    - mother owns background threads and can run background tasks, including cpu-side animation.
    - the loading screen with its fancy progress indicator was dropped in its entirety. The logic remains frozen until first successful render but keeps sending render jobs. The render jobs fail with un-actualized assets, causing some assets to actualize each frame, and replacing themselves with a console render job. So "loading screen" is the console with, maybe, a low-res background image.
    - the error recovery screens were dropped, application displays console with BSOD background and "Press Esc or Back to exit".
    - Kakan manages jobs opaquely to the logic. It sorts jobs by render targets automatically, calculating their order based on where that texture is a texture and where it is a target.
    - Depth/stencil are managed by Kakan opaquely, targets could only be textures. Reason: targeting Mali 400 as the minimum, so depth/stencil do not actually exist and cannot be reused with another color attachment. Need a depth pass? Stuff its output into a RGBA8. Preferably in 128x72 resolution.


    The design document for my first planned game has no English translation yet, also my websites are down due to unsuccessful hardware upgrade (the venerated SATA controller dated 2006 finally gave up the ghost, sees my Samsung HD204UI drives as "ASSMNU GDH02U4 I" glitches with random-generated capacity)


    P.S. See this nightmare:
    SNIPERS: A Nightmare for Developers and Players https://www.youtube.com/watch?v=lOebGm_jMLY
    - and that's why my planned game does not have hitscal weapons at all.
    "Sniper" will be one of ninja's load-outs, heavily influenced by the TF2 "Lucksman" (sniper's bow that fires arrow projectiles).

    P.P.S. When playing competitive first person shooters, no one wants "serious". What people want is slapstick rumble. So any foolish developers who try "serious" style soon give up under players' pressure, their artsy black ops noir degenerating into slapstick comedy. Compare to the wisdom of Valve who made TF2 slapstick from the start (and also reaped immense profit on cosmetics and taunts).
    So, the further away from a mil-sim, the better. More. More distance. Make spells, not weapons. Use in-universe reason for player avatars being something like shadow clones, so that they dispel or unravel with zero blood.

    P.P.P.S. My solution to the problem highlighted in the video above: make the snooper rifle shoot on release, like bows in Mount & Blade. Like a mini-game. The need to lead your vic-- ahem, target is already there. Combine that with firing in the appropriate time window... Otherwise suffering outrageous penalties to accuracy. So that a zero-time instant shot goes wide most of the time and holding LMB for too long adds increasing sway.
    Last edited by Chebmaster; 19-02-2023 at 03:07 PM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •