---------------
Gameplay Notes:
---------------

- Feed Ducks in a relaxing courtyard.

- Bask in the pitter-patter of raindrops on the ground and HUD.

- Gaze into the reflecting pool.

- Meditate on the sounds of your footsteps.


---------------
To Install:
---------------

Setup a default hierarchy of Aleph One with Marathon Infinity data files. Aleph One version 1.7+ is required.

Navigate to the corresponding Aleph One User Data folder. (Ex: UserName\Documents\AlephOne)
Alternatively, use the directory containing the Aleph One.exe executable.

1) Move the 'TranquilCourtyard' folder into the base directory. (Ex: UserName\Documents\AlephOne\TranquilCourtyard)

2) Move the 'TranquilCourtyard_Plugin' folder into the Plugins sub-folder of the base directory. Create one if it doesn't exist. (Ex: UserName\Documents\AlephOne\Plugins\TranquilCourtyard_Plugin)

3) Start Aleph One 

4) Select 'Tranquil Courtyard Map.sceA' as the map under "Preferences/Environment/Map". The map file lives within the 'TranquilCourtyard' folder.

5) Ensure the 'Tranquil Courtyard 1.01' plugin is enabled. "Preferences/Plugins". Disable all other Plugins to be safe.

6) Check the Setting Requirements below: 

"Preferences/Graphics"
OpenGL: On
Resolution: 16:9 or 16:10 Widescreen, tested with 1920x1800
FPS interpolation: 60+ Recommended
HUD Plugin: Tranquil Courtyard

"Preferences/Graphics/Rendering Options"
3D Models: On
Transparent Liquids: On
Bump Mapping: On 
Scripted Effects Quality: Any besides Off

"Preferences/Sound"
3D Sounds: Recommended to be turned On


Film Playback, Multiplayer, and Lua saving are not supported.


---------------
Versioning: 
---------------

v1.01
-- Changed "\" to "/" in mml folder paths. Fixes file loading on Mac OS and Linux.

v1.0
-- Initial Release


---------------
Postmortem/Misc:
---------------

In this section I break down different gameplay aspects, both technical and non-technical, and mull about the decisions made.
Credits section is at the end of this document.

<- Initial Concept ->

While working on another scripting prototype, I watched one-too-many raytracing videos, and wondered if the cylindrical landscape transfer effect could be abused to make a pseudo reflection. The initial trial with a half-split and mirrored landscape was convincing enough, so I began to scope creep the tech demo. What would make a good environment? A park and garden were the first thoughts. Unfortunately, nearby tall objects like trees, like one would have expected in a park, would not be reflected in the water. A garden, or lake with a clearing might have fared better, but also would have required new fauna assets. Ultimately, a stone sculpture garden was decided upon, and a sad office park seemed dreary enough to fit. Notice that even in the final build, parts of the scene such as the walls and building are kept away from the reflective surfaces so the reflections maintain sky assess to support the illusion.

Once it was decided that there would be a reflective pool of water in a courtyard, what would be something interesting for the player to do? People are always feeding ducks at the park, so why not in the courtyard? Ducks kind of appear anywhere there's water + food anyways. To add something whimsical, the idea was formulated that after a crazy amount of ducks had gathered, they would either transform into, or become scared off by, a GIANT MUSCULAR DUCK. Alas it was not meant to be.


<- Abandoned Muscular Duck ->

The Muscular Duck would have been a 1-on-1 boss battle where the player had to fight using only their fists and bread. The boss would move extremely slowly, and, similar to the footsteps in the final mod, each step would have made a loud *Thump* accompanied by the custom HUD moving/shaking. The boss would have had their primary close-range fists, left and right jab. To add some tactical spice, a long-rang 'fist' shockwave or PSY fist, would also attack from afar. The Boss might also channel their energy and 'spring' towards the player, via their walking sprite becoming the projectile. The player could distract the Boss by throwing bread, so the Muscular Duck would attack that instead, and give opportunity to land a few punches. All this of course requires some deep low bellowing *QUACK* sounds as accompaniment. If the player was killed, a possible 3rd person 'kill-cam' with the Security Officer's torso and upper body being split apart was considered.

So what happened? 

One easy non-answer is that the courtyard arena became a bit cluttered for a boss battle. I used the Monster Impassable Polygon Type to corral ducks into the pool, so that would have roughened the boss pathfinding. Of course, these limitations probably could have been worked around, such as teleporting to a replicate arena-specific battle map.

The 2nd, more truthful answer is I ran out of motivation to do it.

For the actual duck model, I produced a concept art slide deck of duck poses and animation keyframes which a commissioned artist transformed into a 3D model with animations. The model was cute, and the animations were nice, but there were some slight issues. For one, the animations were not symmetrical along the long axis due to some strange bone posing/anchoring. The original intent of doing the commission was to not deal with animation woes, but alas I learned enough in Blender to re-key the animations. The next step was rendering the animation frames out. This also took some time, but I had some test exports made that looked promising. However, by this point I was also using the 3D models in-game, and they didn't look half-bad. Furthermore, the 1 3D frame animation per sequence was not too jarring. So, looking upon the pile of work necessary to put the duck sprite sheet together with ShapeFusion, I decided to drop the 2D sprites.

So then with the Muscular duck, an even more complex animation set would have been needed, and, unlike the base duck, the timing feedback from a charge-up animation or punch would be critical. Furthermore, the 3D CAD had not yet been commissioned, and would have likely brought further iteration challenges and time sinks. Therefore, like many proposals, the Muscular Duck was a casualty of its own complexity.


<- Toying Around with The Tech ->

The novel aspect of the media reflection is the ability to stack two horizontal texture layers via the media's transparency. The vertical walls could already stack vertical transparent texture layers, so I considered what interesting effects could be applied with that baseline.

Having a faintly translucent 'waterfall' vertically scroll around the perimeter walls and windows looked fake and bad because in reality, unless it's a rainstorm, not that much water actually drips all at once. I wanted to have transparent textures that also use the landscape transfer effect as a 'cubemap' for the building's window. In this way you could see subtle reflections of the scene in the windows. Unfortunately, the landscape transfer effect does not support transparency. (Feature Request?) Likewise, it could not be used to add a shifting semi-transparent specular effect to walls to make them appear extra wet. That said, I think subtle specular effects could be created with Lua by adding a semi-transparent layer, and then correspondingly shifting it in relation to any movement the player makes.

Instead I figured it might be neat to make 3D-looking raindrops on the windows that utilize the bump mapping feature of the Aleph One engine. To do this, the Metaballs feature in Blender was used to create some stationary 3D droplet meshes in various states of merging. Then, the render pipeline was adjusted at length to get reasonably looking droplet translucency. The real challenge is that while light distortions and caustics through the droplets can be simulated in Blender, they eventually get baked into a static texture. Viewing through the droplet in-engine, at best you see a pleasing partial transparency gradient faking some of distortion directionality.

When it came time for the bump map layer, I was completely out of my element, and the final result is probably not correct. It's definitely there in some capacity, just not accurately.
Some of the intricacies of the Blender pipeline that I wasted too much time on were:
1) Ensuring the color space and gamma were proper correct (sRGB?)
2) Remapping a -128-128 output range to 0-256. In other words, shifting -1 to 1 to 0-1. (Idk though, can't fully remember)
3) WorldMapped Vs TangentMapped. I think I generated a WorldMapped Normal where I understand OpenGL to prefer a TangentMap?
4) Building a 'Mist' layer with enough z-depth that could then be added to the Alpha layer of the RGBA normal texture.

I'll have to revisit bump mapping with Blender later.


<- Vibing with AI ->

This mod has both a HUD Lua script and gameplay Lua script. While I'd dabbled in HUD Lua before, I hadn't tried to interface the two. As such, a good deal of time was spent just figuring out what the functions are supposed to do. This is where I bring the AI into the picture. I'd say that Google's Gemini 2.5 wrote about 60-80% of the code, but it definitely did not save 60-80% of the time necessary to write that code. The AI was best at writing nicely structured functions, however it was weakest at troubleshooting. It was up to me to understand how the game engine specific pieces might fail.

To go a little deeper. On previously mod projects, I had been copy-pasting the Lua and mml manual contents into the Studio AI interface along with my prompt. This worked ok, but the pasting seemed to lose a lot of the positional relevance of the subfunctions. For example, Gemini might get confused that .ticks is a callable function of Game because Game.ticks is not explicitly written in the manual. What helped improve performance was building a short corpus of relevant documents, such as the Infinity Manual, mml manual, etc. and attaching them as their full document format (pdf, html etc.) so that positional context might be better inferred. Also, including multiple documents likely narrowed the scope of response to a more streamlined context.

Other times we'd be confused together regardless. In one case, the mml reference manual under <player> discusses 'Idle-Weapon Torso Sequences', 'Charging-Weapon Torso Sequences', 'Firing-Weapon Torso Sequences' where the weapon options like 'Fists (defaults: 1, 1, 2)' etc. are shown only under 'Firing-Weapon Torso Sequences'. What did not click for either me or the AI agent was that the 3 numerical values refers back to the other sections in order. In some ways, it was reassuring that I was not missing something obvious in my confusion. 

How I then used the AI was as a coding buddy / document searcher. I would ask it to generate some code, which was typically returned with errors, and then I'd see what functions were used, and why they would be assumed to work. It was also useful to bounce ideas off of. Sometimes I'd consider an alternative method only because the AI gave a good/bad response. 

The Gemini Flash 2.0 image generator was also put to work on generating the bread bag, and bread texture. The bread texture was decent, and saved me a trip to the supermarket. I was also struggling with using noise to generate the bread nooks and crannies depth maps with Blender, so it saved me there. The bread bag was ok...however despite being a pixel-art style, each 'pixel' was extremely noisy. I will chalk this up to the Flash 2.0 image generator already being outdated, and the token return limits in the AI Studio interface being limited.

As for the interface hand graphics, AI usage was more limited than you'd suspect. I based them off the shotgun sequences, and in-painted with 'content aware fill', 'AI', human intuition etc. Why are there only 3 fingers + 1 thumb? Because the hand sprite already looked like there was only 3 fingers + 1 thumb! Despite AI's reputation at finger failure, the AI had nothing to do with that in this case. Haha. Is the player a Simulacrum? Let's pretend it's all intentional part of the lore.


<- Rain, Story & Map ->

Why would someone head to a courtyard? Are they seeking refreshment? Relaxation? Perhaps they're depressed? Let's capture that potential moodiness with the weather and add some soft rain. Ducks don't care about rain anyways!

Now precipitation had been done with other scripts before, but I decided to roll my own for closer familiarity. At the expense of more CPU burden, the rain droplets actually leave behind splashes where they land. However, raindrops tend to only splash on hard surfaces in real life. To replicate that, specific Polygon Types were used to dictate splash appearance. This contributed to further plans. Soft ground materials absorb raindrops without visible splashes because they are smooshy. Can we reflect that feeling with footsteps? Inspired by recent engine 3D sound improvements, the step sounds were spatially grounded in the world to sell their 'Left-Right' movement. The choice of step sound varies based on the same Polygon Type concept. I recall that Marathon mods had done footsteps before but I'm not sure if they have done material-specific ones? 

I run out of enthusiasm quickly when it comes to the mapping workflow, so the maps are kept very simple. Using the Polygon Types as a material reference also added another layer of complexity to keep track of during the mapping process. I'm sure the environment could be made nicer with more doodads and texture details. Given unlimited energy, it'd be nice to give the path some additional edge texture styling and/or glowing path light sceneries. 

A custom HUD script to add the rain droplets, which themselves were a scope creep, meant the loss of the default HUD interface. As such, the elements of the game world felt more importance. To elevate that experience, I figured that the text in the margins as a signal of the characters thoughts would be a constrained way to hint at a world beyond the immediate raindrops and ducks. There was also probably some Skyrim inspiration for that fade effect. :)


<- Other Quirks, Observations, & Comments ->

3D Bead cuts into wall when thrown:
	Projectiles don't seem to detonate on their 'radius' set within the Physics File, (IE not spherical hitbox, or that setting is for explosions only) so I'd have to custom-calculate a radial hitbox for wall offset from detonation point. Didn't seem worth the effort.

3D Bread doesn't stack:
	Ephemera don't have hitboxes. The simple remedy is detonate bread on all surfaces to prevent accumulation at all. But I figured there is expectation of the bread to 'exist' in the world since they exist on the water.

Cannot pick-up bread on ground:
	Creating a bread ammo item upon ground impact, rather than Ephemera, is possible. However, because the player has unlimited bread, it seemed a distraction to allow retrieving fallen wet soggy bread.

Quieter Polygon Sounds:
	Regarding the reflective floors that use a thin media layer for the texture - If sounds are generated 'under' the media, they are quieter. With Lua I usually moved actions/sounds up to the Media height, but not always. Similarly, I didn't want to ship a replacement sound file, so many sounds are shoehorned into existing slots that might not have the most desirable attributes such as 'Ignore Media'. 

Duck Crosshair: 
	It should have had gradient mask but I had trouble getting the gradient alpha to work. It's kind of an Easter Egg anyways.

Keyframed Firing:
	It seems that weapons generate projectiles on their first frame regardless of what the sequences keyframes are set to. As such, the hand could not have a 'squish' pull-back animation before the actual bread throw.

Reload Recoil Height:
	Attempted a smoother motion animation for the hand graphics during and after the throw by using the interpolation between the Recoil Heights and Reload Heights. Looks smoother with higher interpolated frames.

3D Animations:
	Aleph One supports the Dim3 format for animations, but I do not know of a modern way to generate that file format, nor any supplemental supported format that allows for animations.

Projectile Facing:
	a) When a projectile detonates, it does not seem possible to grab it's facing in Lua via Triggers.projectile_detonated(). Therefore, in the case of the 3D bread projectile, I just set the stationary bread ephemera to the player's look direction. [Either the player is looking and they might notice the subtle angle error, or the bread is out of view and the player has to remember the real angle when looking back.] The workaround here is to have an invisible projectile to control the pathing, and then use a bread Ephemera as the visual object. Historically, I've had some trouble keeping index linkages, so I opted for KISS on this release. 
	b) I originally wanted the bread to spin once it left the player's hand. However, projectile facing controls its movement direction. This is mostly a non-issue for a 2D sequence that can animate separately from the facing, but 3D model facing will match the projectile facing. So, manipulating 3D model spin through projectile facing would affect its travel path (not desired). Once again, the workaround is the ephemera approach described above.


<- Final Notes & Next Steps ->

Overall, I'm satisfied with the project and have no immediate plans to add anything else. Below are some last minute misc development ideas:

a) BOBs/Marine enemies feeding ducks
b) Play as a duck and eat as much bread as possible thrown by BOBs. Outcompete the AI or other players.
c) Improve the scripts to allow multiplayer, then individually compete for most ducks fed.
d) Muscular Duck lives!
e) 2nd 'secret' ending where the player goes to the beach/lake and throws skipping stones across a reflected sunset.


---------------
Credits:
---------------

Feel free to fix/edit/re-release this mod.
Consider contacting me beforehand on Reddit/Discord/Pfhorums @ Zott820 in case I have a bug-fix in the works, or to access the raw files.


Definitions & Clarifications:
CC0 = Creative Commons 0 \ Public Domain
AI generally cannot hold copyright.


All rights to Marathon Infinity assets remain with Bungie.


<- Art Assets ->

3D Bread & Breadcrumbs
CC0
Textures generated by Gemini Flash 2.0
Modeled and UV mapped in Blender by Zott820

Bread Bag
CC0
Generated by Gemini Flash 2.0, Alpha masked by Zott820

3D Duck
by Ichata from Fiverr under commission from Zott820.
Restricted. No formal written license agreement but per artist's gig page: "Commercial or any use is allowed. However, I retain full copyright."
As such, re-distribution of the duck asset should probably remain within the context of this mod only.

Water Droplets on Glass
CC0
Modeled in Blender by Zott820

Duck Crosshair
CC0
by Zott820


<- Music ->

Dancing-Bee by Art Flower
CC0 1.0 Universal per FMA website.

Säkkijärven Polkka Eurobeat Instrumental by TurboAlt
"...feel free to use any and all of my work for your own purposes!"


<- Sounds ->

Freesounds.org, all CC0
244329__squashy555__ducks1
324087__iggyf__north-yorks-mallard-frenzy_2
613155__dbs_sounds__feethmn_footsteps_on_wet_dirt-road_zoom_h4n_pro
553241__nachtmahrtv__wet-footsteps
530588__nox_sound__footsteps_boots_tile_mono
209582__zott820__artificial-firerain-10-second-loop

Other sounds by Zott820, CC0
Eat, Rustle


<- Scripting ->
By Zott820 and Gemini 2.5 
Reuse as desired. Attribution appreciated, but not required.

