Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

Train Simulator

Train Simulator is a C++23 first-person passenger experience built with CNA. It follows the fictional Northern Valley Express over a deterministic 286.4 km railway while the player walks through a six-car electric train, uses a passenger toilet, takes a seat, watches the world through the windows, and shares the service with an active avatar population and conductor.

This repository is an early but playable showcase foundation, not a finished commercial game. Its simulation, interaction, streaming, UI, audio, and procedural rendering systems are integrated and tested. Visual realism is under active development: materials, lighting, station composition and scenery are improving, but repetitive geometry and stylized avatars remain substantial gaps. See the evidence and open findings in the realism audit; passing automated tests does not certify visual realism or resolve the reported intermittent physical-mouse freeze.

The current ranked screenshot campaign is tracked in the visual audit. See the development handoff for verified progress, remaining work and build constraints.

Screenshots

The committed captures use the real first-person camera and current High quality profile. At the requested frame the application freezes simulation, completes the normal serialized CNA-avatar warm-up, and only then reads the framebuffer, so the simulated saloon and platform populations cannot be hidden by asynchronous startup.

Passenger saloon

Populated passenger saloon with a clear six-car aisle, information displays and ceiling ventilation

Live passenger information

Interactive onboard passenger information with the complete route, train position, speed and following calls

Lakehurst approach

Seated window view across Lakehurst

Stonebridge station stop

Live Stonebridge platform board and CNA station passenger seen from a real window seat

Live route map

Non-pausing route map at Stonebridge

Regenerate all five 1280x720 images from the current executable without manual input with:

./tools/capture_showcase.sh

The script uses throwaway default preference files, so an earlier local FOV or comfort-menu change cannot alter the committed framing. Each capture is decoded and checked for complete HUD glyph coverage before replacing the existing PNG; an incomplete CNA offscreen readback or failed process is retried up to four times.

Visible-window play is the authoritative visual path. See the known offscreen readback limitation below before using long accelerated captures for pixel comparisons. The screenshots are project output rather than external art assets and may be refreshed as the procedural art direction evolves.

Current experience

  • Six connected passenger cars with sensor-operated glazed gangway doors, sealed glazing, illuminated request sensors, ribbed metal kick plates, layered vestibule end-wall panels, flexible bellows, lit inter-car thresholds and anti-slip bridge plates, individually modelled seats with contrasting upholstery seams and piping, passenger-side headrest covers, rear shells, grab recesses, literature pockets and aisle armrests, physical facing-seat tables with cup recesses and power outlets, a woven-edge and transversely bound continuous aisle runner, luggage areas, racks, grab poles, suspended grab handles, ceiling PA speaker grilles, paired climate-control diffusers and individually colored luggage with a visibly busier dedicated luggage car, updating double-sided information displays with station, destination, speed, ETA, following stops across rotating pages, and platform-side door guidance; an interactable full passenger information view adds a live twelve-station route line, train position and direction, plus illuminated passenger door buttons, physical quiet, work/table, accessible, family, luggage, and standard-car identity signs with restrained matching upholstery accents plus close-role details such as books, laptops, assistance controls, play blocks, route literature and a full-height luggage stack; low-poly rounded cushion, back, armrest, and table edges plus slim seat pedestals with visible floor anchors and separately plated table stems soften the foreground silhouette, while wall-mounted extinguishers, emergency intercoms and illuminated exit pictograms in every vestibule, rounded wheeled luggage with pull handles, inaccessible double-ended cab shells with direction-aware live controls, labelled staff-only bulkheads with observation windows and contextual feedback, a visible active-cab driver, real passenger-door openings with glazed sliding panels, jambs and highlighted thresholds, and a signed accessible toilet with toilet, sink/faucet, visible mirror approximation, support rail, emergency pull cord, paper and soap dispensers, anti-slip floor, local lighting, ventilation detail, and a physical available/occupied indicator shared by player and NPC use.
  • Stable train-relative first-person walking, collision, context interaction, smooth seat-camera transition, level platform boarding geometry with a 20 cm horizontal gap, coping stones, safety lines, segmented tactile paving and correct-side retractable bridge plates, window-bay-aligned seats with unobstructed views, low-opacity tinted glazing with subtle quality-scaled view-angle reflection accents, quality-scaled ceiling and upper-wall reflected-light gradients, modular ceiling seams, continuous wall coving/skirting, and restrained vestibule traffic wear, visually segmented resilient vestibule flooring aligned with the surface-aware footstep zones, and comfort-scaled rail vibration, suspension sway, acceleration/braking pitch and curve lean.
  • Continuous relative-mouse look consumes CNA's per-frame deltas directly instead of differencing them as positions. Project capture, CNA relative mode, and desktop focus are reconciled every frame; focus loss or stale mode explicitly releases the cursor, while map, help, display, and pause overlays release it intentionally. One click safely reacquires it.
  • 34 onboard CNA avatar passengers, a bounded two-identity station waiting pool, a conductor and driver, with authoritative seat ownership, smoothly blended custom seated bone poses, distance-driven procedural walking gait with ankle and toe follow-through over varied upper-body idles, seat-anchored stand-up transitions with aisle-facing weight transfer, paired conversational gestures with partner-facing head motion, slow standing/seated gaze, short aisle-side conversations with reciprocal seated/standing eye contact and restrained single-arm gestures, window-view scanning, nearby player acknowledgement with restrained torso follow-through, deterministic two-handed reading idles, and visible screened-handset checking poses, lightweight walking/idle/window behaviors, exclusive enter/use/leave toilet visits, approach-time walks from real seats to the vestibule, visible platform-side boarding and alighting, and contextual service information plus visible passenger-area inspection stops from the conductor. The conductor carries a dedicated screened handheld terminal and uses a two-arm inspection pose.
  • A 12-station bidirectional service with smooth acceleration, cruising, braking, correct-side platform state, 120/140/160 km/h segment limits, an authored 135-minute timetable with live early/late prediction, animated platform-side passenger doors, a shared animation/AI passage interlock that keeps boarding actors behind the leaves until the opening is clear, terminal reversal, and indefinite operation.
  • A deterministic, bounded 250 m chunk streamer with broad relief terrain, countryside, urban density with footprint-aware railway setbacks, broad city approaches, endpoint terrain aprons and terminal skylines, hazy distant ridges, seeded broad field parcels with segmented crop rows and low terrain-following hedges, occasional strapped straw-bale stacks, terrain-bound grass clumps, bushes, forked tapered trunks and distance-bounded faceted broadleaf/conifer crowns with stepped branch silhouettes, deterministic palette variation, terrain-following understorey and mixed-age sapling clusters on Medium/High, distant woodland belts, shallow terrain-cut lineside drainage with quality-scaled outer-bank grass outside both fences, coherent 500 m field-tint parcels with segmented terrain-following hedges, desaturated far terrain, a quality-scaled second woodland line and muted distant settlement silhouettes, sparse fenced farm compounds with barns and silos, distance-scaled window detail on track- and route-facing building elevations including both end faces of stepped distant towers, and batched vegetation contact shadows, detailed modular houses, bounded city streetfronts, apartments, loading-dock warehouses with slatted shutters, docks, clerestories, cladding ribs, rooflights, rear HVAC plant, downpipes and roof extractors, plus bounded shared industrial yards with gates, parking markings, pallet stacks, planted fence-edge buffers, parked delivery trucks, an occasional service van and detached tandem-axle box trailer, sparse stepped skyline towers behind the densest city approaches, two-sided paved urban streets with footways, lighting, continuous road-edge markings and slotted kerb drainage; urban trees and shrubs remain behind the outer footway, while houses and blocks sit on bounded planted or paved plots with real thresholds and short entrance paths, double track, fencing, protected level crossings with distance-driven striped barriers and alternating red road-warning lamps that react to both the player's service and visible AI trains, plus a quiet matching spatial warning bell, major-station sidings and turnouts with concrete-mounted point motors, drive rods and route indicators, correctly offset catenary masts with contact wire, sagged messenger, variable 25 m droppers, insulators and staggered registration arms, signals, working-limit speed boards, passenger-visible numbered kilometre posts, deterministic signalling/telecom cabinets with louvres, warning plates and cable markers, sparse high-voltage corridors and trackside electrical substations, maintained direction-facing three-lens block signals with live red/yellow/green aspects, named stations, curved tunnels with low-cost wall/ceiling luminaires, reflective guidance, raised evacuation walks, structural joints, and signed emergency niches, a level streamed Lakehurst shoreline with a carved basin, mipmapped directional-wave material, shore-to-depth colour, reeds, surface glints and a quality-scaled layered woodland silhouette on the far bank, a level reflective river/estuary crossing with dark steel fascia, concrete abutments and broad blade piers, and a separately modelled wooded dry-valley viaduct with concrete parapets and paired slender shafts; both use curve-following 20 m deck sections, underside girders, cross-members, terrain-reaching supports, and open upper railings that preserve passenger views, sparse road overpasses with terrain-reaching ramps, supports and guardrails, lightweight bidirectional road traffic with rounded low-poly bodies, sloped glazing, mirrors, wheels, hub cues and directional lights, detailed articulated passing trains, and short parked services at major stations. AI cars share a batched mesh with individual windows and doors, end gangways, bogies, wheels, underfloor equipment, and roof units; each short consist carries one raised centre-car pantograph aligned to the contact wire. Exposed ends receive distinct driving-cab overlays with side glazing, divided windscreens, wipers, destination pixels, crash skirts and direction-correct white or red marker lights. Moving consists complete a continuous 1.9 km pass before an out-of-view reset, and both their spatial audio and geometry follow the same widened parallel alignment through island stations. Static scenery is batched per chunk transition.
  • A deterministic mipmapped material palette adds fine non-repeating tonal structure to terrain, track ballast, polished rail heads, station concrete, lake/estuary water, carriage carpet, seat upholstery, resilient vestibule/WC flooring, and close passenger-wall and ceiling panels. Medium/High select per-pixel material lighting with restrained surface-specific highlights and wrapped filtering (anisotropic on High), restore the neutral sampler after every material pass, and add batched soft contact beneath buildings, canopies, vegetation, and seat groups; Low keeps the inexpensive path. The runtime reports each material batch independently for visual and performance regression. Rails separately model their oxidized foot/web and wheel-polished head; dark baseplates and paired elastic clips connect them to deterministically varied concrete sleepers, while catenary masts have concrete foundations. Track-facing houses and apartments use a shared rendered-plaster batch, townhouses use course masonry, and station buildings combine a masonry plinth with rendered upper walls rather than perfectly flat facade colour. Nearby passenger-facing windows add projecting pale frames, inset glazing, sills, and quality-scaled mullions while distant openings collapse to one bounded pane.
  • A small culled CNA-avatar platform population at each stop, including a high-visibility station employee, uneven paired travel groups with varied waiting orientation, restrained major-station conversation gestures, a wrist-attached handset, and window-readable wheeled luggage beside alternating waiting passengers, makes station calls feel occupied without creating a persistent city crowd simulation.
  • Normal-based sunny directional lighting over all project-generated geometry, with smooth tunnel darkening, depth-masked window sunlight across the saloon floor, subtle avatar contact shadows, unlit information displays, quality-scaled procedurally textured soft fair-weather clouds and low horizon banks, a soft horizon-to-zenith daylight gradient, and a stable sun cue.
  • Dynamic passenger information, a continuously moving non-pausing route map with live ETA, service state, direction, and explicit passed/train/upcoming legend, diagnostics, comfort settings, speed- and acceleration-reactive rail/traction/braking audio, surface-aware carpet and vestibule/gangway footfalls, a quiet continuously running interior ventilation bed that settles beneath open-platform ambience, successful-movement footfalls, irregular spatial passenger speech-like murmur, spatial passenger, automatic gangway-door and accessible-toilet-door sounds, synchronized spatial whoosh from passing trains, and offline-generated English announcements preceded by a project-synthesized onboard PA chime, with synchronized optional captions and smooth automatic background ducking.

Controls

Input Action
Left click Capture mouse
WASD Walk
Mouse Look
E Interact, sit, stand, open toilet door, inspect display
M Toggle route map without pausing
H Toggle the compact passenger HUD for an unobstructed window view
F1 Toggle controls
F3 Toggle developer diagnostics
F5 Freeze or resume train simulation
F6 / F7 Developer teleport to previous or next station
Esc Pause simulation and audio, release mouse, and open the comfort menu
F12 Quit

There is deliberately no jump action and no way for the player to leave the train or enter a cab. On a normal desktop launch, a compact prompt remains visible until the first left click captures the mouse; Esc releases it again. Developer station teleports may be used even during boarding: any active doorway flow is settled safely and the newly selected station starts a fresh exchange on its own platform side.

Requirements

  • Linux desktop with an OpenGL 3.3-capable driver
  • CMake 3.23 or newer and Ninja
  • A C++23 compiler
  • system ccache
  • Python 3 when building the test suite or regenerating audio assets
  • sibling checkouts of CNA next and sharp-runtime next

The expected checkout layout is:

parent/
  cna/
  sharp-runtime/
  train-simulator/

Only CNA's OpenGL 3.3 renderer is configured. Web, mobile, macOS-specific work, Vulkan, DirectX, and other renderers are deliberately out of scope.

Build and run

cmake -S . -B build -G Ninja \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  -DCMAKE_C_COMPILER_LAUNCHER=ccache \
  -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
cmake --build build --parallel 4
ctest --test-dir build --output-on-failure -j4
./build/train-simulator

The system ccache executable is mandatory and CMake rejects a different compiler launcher; its normal per-user cache location is sufficient. Never raise build parallelism above four. The repository uses one incremental build/ tree and copies its small runtime asset set beside the executable.

To create a relocatable Linux desktop tree, install into a chosen prefix. The install includes the executable, CNA and SDL runtime libraries, assets, project/dependency licenses, and asset/audio documentation:

cmake --install build --prefix /path/to/train-simulator-install --strip
/path/to/train-simulator-install/bin/train-simulator

Validate the complete installed layout in a temporary prefix, including origin-relative CNA/SDL linkage, sidecar assets, and an OpenGL 3.3 application smoke launched outside the repository, with:

./tools/verify_install.sh

The verifier removes both of its temporary directories on success or failure. An alternate incremental build directory may be supplied as its first argument.

For seated-avatar visual inspection, --passenger-view --car 2 starts in the aisle looking obliquely toward an occupied seat. Allow approximately 180 frames for avatar loading before a capture. This inspection view is mutually exclusive with the other --*-view presets.

Useful launch options are --time-scale X, --development-dwell, --debug-overlay, --help-overlay, --map-overlay, --inspect-display, --pause-overlay, --hide-hud for an unobstructed initial view, --no-audio, --frames N for automated smoke runs, --run-seconds S to stop after S unpaused simulation-update seconds (before journey time scaling), --station N to start at station 1-12, and --route-km X to start a moving QA ride at an exact route kilometre. Pair either location option with --direction -1|1 to validate a particular service direction; endpoint safety still selects the only possible onward direction. --car N selects passenger car 1-6. --quality 0|1|2 applies the production Low/Medium/High profile for a reproducible QA run without altering the saved preference. --window-view starts genuinely seated at an available right-side window in that car (or car 4 by default), while --left-window-view uses the equivalent left-side seat, --platform-view instead reserves a real window seat on the current or upcoming train-local platform side, preferring the clearest central row in the selected car, --door-view starts at that side's passenger threshold and looks down across the deployed bridge plate for boarding-geometry QA, --sink-view frames the washbasin, tap and mirror inside the closed toilet for visual QA. --toilet-view starts inside the open accessible toilet for visual QA, --gangway-view starts beside an automatic inter-car door, --vestibule-view frames the extinguisher and emergency intercom on the selected car's vestibule end wall, --sunlight-view looks down across a complete window-light patch, --signal-view reserves a real window seat and aims the production camera at a generated facing block signal while holding the service for a repeatable capture (F5 resumes it), and --screenshot PATH writes a final-frame PNG. Runtime assets are discovered beside the executable, in an installed share/train-simulator/assets layout, or in the working directory; --asset-dir PATH provides an explicit override for packaging and QA. --config PATH selects an explicit user preference file. --no-avatars is a diagnostic/test-only fallback for isolating CNA avatar-loader lifecycle issues; ordinary play and the showcase captures keep the complete avatar population.

For repeatable environment QA, --audit-camera X Y Z YAW PITCH overrides only the render camera (train-local metres, render-space height and angles in degrees). It requires --frames and --screenshot; normal gameplay still cannot leave the train. See the 120-finding visual audit and tools/capture_visual_audit.sh for the baseline capture poses and repair evidence.

For an intermittent camera/input issue, launch normal play with ./build/train-simulator --report-state > build/input-session.log 2>&1. Without a finite --frames limit this flushes an INPUT_TRACE every five seconds, including window focus, native/project mouse capture, all look-blocking overlay states, cumulative look-motion samples, view angles, player position, drawn-frame count and the actual wall-time interval since the previous trace (zero for the first record). An interval much longer than five seconds exposes a stalled update loop instead of silently resembling missing mouse motion. It does not record typed text. Note approximately when the problem occurred and retain the log; F12 exits if input still responds. These diagnostics do not claim to fix the reported intermittent freeze. The optional isolated X11 probe and its limits are documented in Architecture. For an isolated GPU-backed Xwayland probe, use INPUT_PROBE_BACKEND=xwayland INPUT_PROBE_QUALITY=2 INPUT_PROBE_PHASES=12 INPUT_PROBE_AVATARS=1 bash tools/test_x11_input.sh. This requires the sibling CNA private Weston runner and does not operate your desktop. Check build/x11-input-test/renderer.txt for actual acceleration; synthetic events still cannot certify the physical-mouse issue.

--no-vsync is a diagnostic presentation override. It keeps the normal 60 Hz simulation target and all quality settings, does not alter saved preferences, and may cause tearing. Compare it with the default synchronized run when investigating frame pacing; vsync_requested in the final report records the requested setting, not proof that the driver honored it.

--variable-step is a timing diagnostic that disables CNA's fixed-step wait without changing the VSync request. Use it with --no-avatars for timing comparisons: avatar preset playback still contains per-draw timing assumptions, and this switch is not a supported gameplay/performance preset. Without effective VSync it can run uncapped. Normal launches keep the fixed 60 Hz target. fixed_time_step in final telemetry records the selected mode. A matched private GPU comparison still measured approximately 26 ms with either mode; switching did not fix synchronized pacing.

--report-state prints final route, direction, phase, speed, simulated service time, leg, loaded/generated streaming, population, active driver car, seat-walker, player-yield response, active/started station-exchange, offboard, draw-call, triangle, visible-avatar, avatar-rendering-mode, quality-budgeted avatar-pool, and fully ready avatar-pool counters, including active distance-driven gait and seat-exit layers, for automated soaks, together with visible signal-aspect, live platform-board, platform-phone, platform-social-pose, platform-planter, platform-luggage, canopy-drainage, quality-scaled sky-cloud and understorey, industrial-compound, yard-vehicle, trailer, warehouse-utility, industrial-edge-planting, urban-road-edge, road-drainage, residential-plot and entrance-path, Lakehurst water-patch, station-waterfront, far-bank-tree and rural hay-bale-stack counts, nearby kilometre-post, catenary-dropper, rendered external-train car/cab-end, turnout-motor/blade, nearby station-clock-hand, and level-crossing barrier/lamp/audio counts, visible animated road-vehicle, tunnel-luminaire, tunnel-safety-niche, river-water-section, total/river/viaduct bridge-section, and loaded bridge-abutment counts, wall-clock render FPS, active tunnel/bridge acoustics, occupied-toilet indicator state, and visible interior-sunlight patches plus passing-train/passenger-door/toilet-door and carpet/resilient floor footstep audio event counts, live traction/braking effort, automatic-announcement chime/event/caption state, successfully started terminal announcements, and nearby passenger-murmur playback count, route-map/passenger-HUD/display-inspection/pause state, authoritative longitudinal acceleration, visible suspension response, deployed boarding-step count, distance advanced since launch, and train-local player coordinates, view yaw, seat/stand/toilet-door transitions, and relative-mouse-mode acquisition/loss counts. Run ./build/train-simulator --help for the complete syntax.

--interaction-smoke --no-audio runs the real CNA application through display inspection, sitting, standing, toilet use, conductor interaction, a collision-checked walk through all six cars in both directions, both staff-cab boundaries, and the remain-aboard boundary at a genuinely open platform-side door. It exits successfully only if every state transition and traversal agrees. The smoke also verifies that actual displacement raises—and idle clears—the walking-audio signal, and that carpet and non-carpeted movement choose their distinct sounds. CTest runs it both silently and through CNA's dummy audio mixer, in addition to the deterministic cases, a synchronized passing-train audio smoke, a live four-actor station-exchange smoke, automatic bidirectional welcome and route-aware next-station announcement/caption smokes, a reverse-direction approach and exchange smoke, a Low-profile station smoke that requires its eight-visual avatar pool and a post-warm-up PNG save, a complete rendered terminal-reversal smoke, an accelerated early-door-close recovery smoke, a live non-pausing route-map smoke, a live moving passenger- information diagram smoke, a left-platform seated-view smoke, paired left/right platform-door bridge-plate view smokes, vestibule safety-equipment and accessible-toilet occupancy, generated-signal and passing-train window-view smokes, synchronized visual/audio level-crossing smokes, paired streamed tunnel/bridge geometry-and-acoustics smokes, a right-window urban road-traffic smoke, a natural-cooldown spatial passenger-murmur playback smoke that also reaches a terminal and requires the queued final-stop announcement to start after reversal, byte-exact regeneration of all 27 synthesized non-speech audio files, a full High-profile showcase-population warm-up, a pause smoke that requires every live CNA audio instance to be paused with no route movement, and a separate-cwd smoke that proves the executable uses its copied sidecar assets instead of the source tree. A serialized install-layout smoke additionally creates a throwaway relocatable prefix, verifies origin-relative CNA/SDL linkage, and launches that installed copy from an unrelated directory. A moving-start interlock smoke also requires all passenger doors and bridge plates to be retracted before the first rendered frame. A separate accelerated-departure smoke proves that the visual leaves and bridge plates cannot lag the service interlock into a moving phase, while also exercising the real door-warning audio transition. Even with development dwell compression, the application grants the passenger system one fully open update before it permits those doors to close.

Configuration

Defaults live in assets/config/train-simulator.cfg. User changes are stored atomically in $XDG_CONFIG_HOME/train-simulator/train-simulator.cfg, or under ~/.config when the XDG variable is unset. An existing train-simulator.cfg in the working directory remains a compatible explicit local override. The user file overlays:

  • mouse sensitivity;
  • master, announcement, passenger, and train volume;
  • camera-motion strength, including zero for no vibration, sway, curve lean, or longitudinal suspension response;
  • vertical field of view;
  • Low/Medium/High graphics quality profile;
  • vegetation rendering distance;
  • synchronized announcement captions.

While paused, the arrow keys adjust field of view, mouse sensitivity, camera-motion intensity, graphics quality, master volume, train volume, announcements, passenger voices, and vegetation range. Changes apply immediately. Quality profiles cap vegetation at 400/700/1000 m, bound dynamic-object range, render the nearest 6/9/12 onboard avatars, and scale platform population, contact shadows, and parked trains while leaving all 38 simulated characters unchanged. Medium and High request desktop MSAA from CNA while Low keeps it disabled; because the back buffer is created at launch, this part of a changed quality preset takes effect on the next launch. The hardware-clamped sample count is visible in F3 diagnostics. Menu changes are saved to the selected user file; it is loaded over the project defaults on the next launch and can also be edited directly. A command-line --quality override remains temporary when another menu value is saved; choosing a new quality in the menu is an explicit persistent change.

Unknown keys and invalid or non-finite numeric values fail clearly, and valid values are clamped to comfortable ranges.

Project layout

assets/                 Runtime configuration and distributable WAV files
include/trainsim/       Public project headers
src/sim/                Route, service, and passenger simulation
src/world/              Deterministic route streaming
src/render/             CNA meshes, avatars, world, train, and UI support
src/audio/              CNA audio playback and route-aware mix logic
src/app/                Game lifecycle, input, interaction, camera, and HUD
tests/                  Deterministic headless simulation tests
tools/                  Reproducible asset-generation tools
docs/                   Design, route, AI, audio, and attribution notes

See the living realism and production audit, Architecture, colour-pipeline calibration, Route, NPC AI, Audio, and Asset attribution.

Known limitations

  • Many walls, buildings, fixtures, and vegetation surfaces still use lit vertex colour while the new material palette is expanded; silhouettes and authored material variety remain active work.
  • Stations share a coherent modular platform language but use distinct authored families: glazed endpoint halls, market-town clock turrets, rural wind shelters, suburban footbridges, waterfront promenades, and elevated city concourses. Level platforms include subtly jointed modular paving, six restrained material palettes, minor/major two- or three-bench compositions, bounded Medium/High surface wear, restrained roof-runoff streaks on station façades and bench contact shading, framed canopies with warm underside panels, and a clearly readable coping/safety/tactile edge plus live service boards with destination, platform, boarding state, ETA, and punctuality; every platform has a numbered sign, station-varied glazed poster cases and vented service cabinets, while major stations add paired planted islands and clocks with readable faces and hands. Their marked analog faces advance continuously from the simulated service clock, including during accelerated development runs and repeated return journeys.
  • Full cast shadows, real-time glass reflections, and authored motion-capture locomotion clips are not implemented; robust contact/highlight approximations and smoothly blended procedural bone layers are used instead.
  • Avatar locomotion remains procedural: seated, walking, and seat-exit motion uses project-authored bone/placement layers over CNA's stock upper-body idles rather than dedicated motion-capture clips.
  • Long accelerated screenshots can intermittently lose 2D spans on CNA's offscreen EasyGL readback; gameplay is unaffected and the investigation/workaround is recorded in bugs.md.

The current supported target is Linux desktop with CNA OpenGL 3.3. Game logic is kept independent of the renderer so future CNA targets remain possible, but they are not developed or tested here.

License

Project source and project-created assets are released under the MIT License. Third-party generation inputs and their provenance are documented in docs/ASSETS.md.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages