UnityTowerDefense/Assets/_Project/Scripts/Core/PoolWeightAttribute.cs
Matt F 4892d7253d First pass at full refactor to 2.0 design
Restructures the game around the cyclical run loop from Game Design Doc V2:
5 waves = a cycle, 3 cycles = a phase, each phase ends in a boss.

- New TD.Gameplay.Waves: WaveGroup / PhaseDefinition / RunDefinition author the
  run as draggable weighted pools; RunState owns phase/cycle position, the drawn
  wave slots, and the per-slot enemy buff sets. WaveManager's flat wave array is
  gone -- it now only runs the encounter RunState points at.
- New TD.Gameplay.EnemyUpgrades: the post-wave enemy-buff vote, with public
  live-replicated ballots so the HUD can show who voted for what.
- Inter-wave flow is now strictly sequential: draft -> vote -> build, each stage
  ending early once every player has acted.
- Enemy abilities inverted from per-instance random rolls to deterministic,
  stacking per-wave-slot sets. Six cards ship: Split (reworked), Flight, Blink,
  No Bounty, Gold Theft, Double Up.
- Tower upgrades are a two-step tree: a draft pick unlocks a node, gold converts
  an already-placed tower in place.
- Boss encounters flag their enemies and drive a boss HP bar.
- Player cap reduced to 3 via MatchRules.MaxPlayers.
- GoldConfig is now keyed by global encounter number rather than wave index.

Compiles clean; NOT yet verified in-engine. Editor wiring still required --
see Docs/2.0_Setup_Checklist.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 17:45:11 -07:00

35 lines
1.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Assets/_Project/Scripts/Core/PoolWeightAttribute.cs
using UnityEngine;
namespace TD.Core
{
/// <summary>
/// Marks a float field as a 01 <b>relative</b> draw weight inside an authored pool. The
/// inspector renders it as a slider and, when the value is zero, shows a warning directly
/// beneath explaining that the entry can never be drawn.
/// </summary>
/// <remarks>
/// <b>Relative, not absolute.</b> Weights are normalized against the summed weight of the
/// candidate set at draw time, so entries at equal weight are equally likely and an entry at
/// 0.5 is half as likely as one at 1.0. This is why every weight field defaults to 1 —
/// adding an entry to a pool then never silently re-weights the entries already in it.
///
/// <para><b>The warning is advisory.</b> Muting an entry while tuning is a legitimate
/// workflow, so the drawer never clamps the value or blocks the edit. It exists because a
/// zero-weight entry is otherwise indistinguishable, in play, from one that simply hasn't come
/// up yet — the failure is silent, so the authoring surface has to be loud.</para>
/// </remarks>
public class PoolWeightAttribute : PropertyAttribute
{
/// <summary>
/// Noun used in the zero-weight warning ("this <c>wave</c> can never be drawn"). Keep it
/// singular and lowercase.
/// </summary>
public readonly string Noun;
public PoolWeightAttribute(string noun = "entry")
{
Noun = string.IsNullOrWhiteSpace(noun) ? "entry" : noun;
}
}
}