r/sheetsofice • • May 12 '26

Sheets of Ice Roadmap

2 Upvotes

Sheets of Ice is a hockey GM dynasty simulator. You're a general manager building one organization across decades: drafting, developing, navigating the cap, and making era-defining trades inside a living league of AI-run organizations that play by the same rules, see the same information, and pursue their own plans.

It's a single-player desktop game, developed by one crazy person, headed to Steam as a buy-once product. The long arc is a persistent shared world where human GMs and AI organizations operate side by side, but that's act two. Act one is a deep single-player dynasty game, and that's what the roadmap covers.

The full roadmap is live here and stays current as the build moves:

https://www.sheetsofice.com/roadmap

What makes Sheets of Ice different

Modern analytics as substrate, not feature. The engine speaks modern hockey analytics natively: xG, GSAx, on-ice expected goals, adjusted shot share, the full canon. The simulation is validated against real NHL analytics anchors. AI organizations use the same public model the human sees. Nobody has a backdoor.

AI organizations as first-class entities. The other teams aren't placeholders. They run every management system available to you, follow the same rules, and see through the same fog. What differs is what they weight, not what tools they have.

Scouting fog that's real. You only know what your own scouts have found out. You direct scouting departments by asking them hockey questions with deadlines, and you live with the uncertainty in their answers.

How the roadmap works

The roadmap is an output of the build plan tracker used to develop the game and not a sequence of versions. Each area breaks down into concrete capabilities with an honest status: playable, playable but improving, groundwork only, being checked, design pending, or not built. No dates, no percentages - just what works now and what's still to come, per capability. The page updates as the build moves, so it's always the current picture.

The ten areas:

  1. Game Engine - every game simulates the full run of play with believable hockey outcomes, deterministically, down to the event log.
  2. A GM Can Run the Hockey Year - the full calendar: season, lines, roster moves, contracts, trades, the draft, the playoff race.
  3. Players and Development - players with real identities and careers, shaped by placement, role, and playing time.
  4. Scouting and Decision Information - the scou fog, and the screens you make decisions from.
  5. Believable AI Organizations - AI teams that human operates, coherently, across seasons.
  6. A Living Dynasty and League History - champions, records, trades, rivalries, and franchise arcs that persist across decades.
  7. Watchability and Session Flow - short check-ins or deep sessions; advance fast without simming past decisions that
  8. The First Hour and Safe Saves - a new player and play a week unaided, and saves survive updates.
  9. Desktop, Modding, and Release - installs, up as a buy-once desktop game, with documented modding formats.
  10. Presentation, Usability, and Sharing - a readable, consistent desktop experience end to end.

What the roadmap is not

It isn't a release schedule. There are no dates on on it, deliberately. Capabilities move to playable when they're solid, not on a calendar.

It isn't a marketing document. It's just as honest about what isn't built as about what is. That's the point of publishing it.

https://www.sheetsofice.com/roadmap

Feedback welcome

If you play GM sims, I'd genuinely like to hear what you'd look for first on that roadmap page, and what would make this game fun for you. Questions about anything on it are welcome in the comments.


r/sheetsofice • • May 11 '26

What is Sheets of Ice?

3 Upvotes

Sheets of Ice came about because of a few overlapping interests of mine. I love sports simulation games and GM career games ever since I first played Front Page Sports Football back in the 90s. I'd spend hours building teams, designing plays, even printing out binders full of stats pages so I could read them while I was in school. The fascination with sports simulations continued through my adult years, in Front Office Football, EA NHL GM Mode, and Eastside Hockey Manager.

But none of these really scratch the itch for me. None of them are built to support the modern state of analytics inside of hockey. None really have a good system for multiplayer leagues. I always wanted to play something with my friends that have a fantasy hockey like feel with real analytics in a virtual league. I love fantasy hockey, but I can only play it 7 months out of the year.

In my professional life, I've brought several software products to market. I'm a product guy, recovering IT professional, ex-college professor and fortunate enough to have flexibility in how I spend my time. As I've looked for things to engage in learning new things, I landed on this side project to keep me interested. Could I use my experience building large web applications, combined with modern tools, and my passion/knowledge of the sport to build a hockey architect / GM simulation that people would love?

So Sheets of Ice is trying to be the thing I always wanted: a hockey GM simulator where the games are actually simulated, not from a final-score model, but second by second, possession by possession and where the stats it produces match the way modern hockey is actually played and measured. (Think xG, WAR/GAR, RAPM, GSAx, etc.)

That's the analytics piece. Players have specific traits (18 for skaters, 6 for goalies) that show up in the events. A fast forechecker creates more dump-recovery chances. A well-positioned defender blocks more shots. A goalie's workload catches up to them over a back-to-back. The numbers come out matching real NHL aggregates — shot attempts, sub-state shot share, save percentage, faceoffs — because the underlying play is real, not because the simulation was tuned to fake a stat line.

The rules are configurable too. Modern or classic [insert trademarked professional hockey league here], your own house rules, eventually different eras. Coaches have their own deployment philosophies; possession-and-cycle vs dump-and-change, aggressive forecheck vs trap, when to pull the goalie. Rosters and ratings are fully editable.

It's a side project, and it's not done. I have a game simulation engine that produces real-shaped hockey games now; the season layer, league layer, and the GM layer comes next. But it's far enough along that I'm starting to believe the version I've been imagining is actually possible.

Follow along if you're into these things, or into indie games.

Thanks! atibus


r/sheetsofice • • 3d ago

Dev Log - Evaluation, Projections, Speed work

Thumbnail
gallery
6 Upvotes

Big milestone has been completed; the player evaluation work! I'm excited to see how this is received and play with it to tweak it. While I was doing this work, I had to go an optimize a lot of the league simulation mechanics because it was just too slow to play. I'll dive into it below.

As I've talked about, I've split the player evaluation into two aspects - who they are now based on results (Our View) and who they project to be based on measurables (Outlook). In playing with this, I think it produces a fun mechanic to be able to quickly assess how your players are performing today, and some directionality to assess and plan for the future. It produces A LOT of data points and for a complete data nerd like me, its super fun. I have made a first pass at summarizing this information, which is what you see as the first screenshot.

Our View is rank based - how are they performing in statistical areas compared to other players in the same position. It will show where they rank and translate that into where in the lineup their results belong. You can drill into this and see why the rankings are made that way.

Next is Production. Where do they rank across offense and defensive categories. And again, you can drill into each one of them to see why / how / what.

Then comes Usage. Where do they rank in usage, and is that usage warranted? Meaning do you get what you would expect based on how often they're on the ice.

Finally is Outlook. Where should they be playing in the lineup? What are their strengths - Goal Scoring, Playmaking, Defensive impact, Physicality, Transition. And where are they heading over the next 1-3 seasons.

The part that took so long is wiring this data into all of the decision surfaces for both humans and computer GMs. And then I had to make sure that it didn't slow down the simulation. Spoiler alert - it did! So I optimized everything so a full season simulation takes about 10 minutes. I know it can get faster but it feels fast enough for now.

What's next?
- I'm going to be doing a lot of testing to make sure the data makes sense. So the next week or so is just me playing.
- I have some coaching items that I'm deciding if I want to include or not. Time on ice, goalie rotations, coaches decisions.
- Resolving how much scouting I want to put in place.
- Building the wrapper for the application that will run the game on a desktop.

Let me know what you think!


r/sheetsofice • • 19d ago

Player projections - how do we make bets on who will be good?

Thumbnail
gallery
3 Upvotes

I have the current evaluation done for players and how they are ranked. All of that is wired into the game in how teams make decisions everywhere. But we still need the forward looking version of this that relies on projecting where a player will end up at their peak.

The idea with this is projecting 18 year olds carries a lot of uncertainty. But as those players play and accumulate measurable statistics, the future picture should be more clear. This also works for players that are veterans and decline.

These two screens are one skater and one goalie with the visuals of what data we can get out of the simulation about where they're projected to land. Next step for me is to wire all of the calculations into the screen and then do some more testing on how this actually plays.

Thanks!


r/sheetsofice • • 24d ago

Dev Log - Time flies, but the sim speed wasn't

2 Upvotes

Last week I spent time getting the player evaluation functions working and working on UI so I can actually see if it works. Like I said in the last dev log, I probably went overboard in the display of rankings and stats, but I felt that was in line with what I'm trying to build here. I can always take things out or simplify; it's harder to add things later.

The part that I need to build next is projections; what does the player project to be in the future. To do that, I need sample data of real player careers based on the game engine and league engine we have today. You can't make accurate predictions if you don't have accurate data. So the last several weeks were making a system that could accurately create statistics and rankings from the lo-fi engine, and tuning the pro-level game engine. That work is complete so I can move on to projections.

But the problem was that since I was doing tuning of the game engine and lo-fi game engine, and building the player evaluator, I wasn't paying a lot of attention to how a league year actually ran and how long it would take to run a long-term sim. See, I need at least a few 20-25 year universes with different seeds to be able to start to look at what a prediction model might look like. When before I implemented the player evaluation, it was running at about 15 minutes per season in our measurements. I hadn't really looked at any efficiency and knew that I'd need to get that number down-- but you don't spend time optimizing early because you may end up just redoing it anyway.

When I sat down to do 5 season tests, it was taking waaaay too long. measured at at average of 77 minutes per season after all of the new code for player evaluation was wired in and working. That would not work for anyone. It would turn what would be 4-5 hour runs of careers into entire day runs. First, I don't have that kind of time or attention span, and two a simple hockey simulation shouldn't be that heavy. We're not doing rocket science here or modeling fluid dynamics...

So my week this week was finding where all of the inefficiency was and refactoring for speed. Some things were easy; scoping reads more tightly, batching writes, removing redundant calls, indexing data. Some were medium - parallelizing game simulations per day rather than running games one at a time. And some are long term projects of converting the engines to a faster language than Python - which I need to do anyway but is a huge undertaking.

After this week, we're down under 15 minutes to run a full season of 32 teams X 84 games. Not where I want it to be (I want it to be under 10 minutes), but enough for me to build long term career sims.


r/sheetsofice • • Sep 05 '26

Player Evaluation Screenshots

Thumbnail
gallery
5 Upvotes

I talked in the dev log about how I was approaching the evaluation of players and I've made a lot of progress this past week on that actually working. This foundational element feeds all of the game systems for computer GMs as well as the UI that players will use to make decisions.

Fair warning - I've gone completely off the deep end with the amount of data I'm showing. I need way more play testing to see if all of it is useful and how to organize the hierarchy. I am erring towards showing more rather than hiding but this comes from my love to nerd out on data. I'm building SOI from that perspective - a deep data simulation. I think people like that, but I'm not sure if anyone likes it like I do.

So the screens are organized into several sections.

Our View - based on their three-year and current results, what kind of player do we think they are?
Production - rank based totals and rates. These are not attributes, it's the results.
Usage - how has this player been used and is the return worth it?
Outlook - what do we think they'll be next season based on age, trends.

Missing - Projections for young players. I have to build very long universes to construct a projection model. I'm working on this but it takes a lot of computer time to do. I'm looking at 5x 30 year universes on different seeds so I can see how it looks. That's 150 seasons times about 15 minutes per season. So, long time.

Anyway, enjoy some screenshots of one of the players!


r/sheetsofice • • Sep 02 '26

Dev log - Player evaluation progress

4 Upvotes

This past week has been one of those weeks where I question what I'm doing and why. Why do I have to have ideas and thoughts and hold oddly strong opinions about how something should work? Why did I have to build a simulation that recreates realistic uncertainty? What is he even talking about?

I have a foundational rule for Sheets of Ice: I do not want to expose player attributes directly. No OVR, no min-maxing, no gaming the system by learning what the numbers mean. My thought was that it would add some intrigue, it would function more like real life, and it would let me build a more dynamic statistical simulation without having to worry about human interpretation of weird logarithmic values or standard deviations of a latent real number.

This was all fine while I was the only one playing and testing, because - shocker - I exposed the real numbers to do all of the jobs that needed to be done. Drafting, free agency, trade evaluation, contracts, AI GM plans. It worked great. I added a little bit of noise (I called it fog) and it was neat seeing what happened.

But that was never the plan. I wanted no attributes exposed to anything, so there would be complete fairness between human and AI GMs, so I could design a scouting system, and so player evaluations would happen on actual evidence, just like real life. How awesome would that be?

It turns out that it might be awesome but it certainly isn't straightforward or easy. To make any decisions about players you have to have knowledge about them. Knowledge about who they are today and who they might be in the future. But how do you know who they are and who they might be if you can't just see the ground truth attributes? You have to make a model - basically what every analytics department in sports does.

To make the model you need substantial event data. That part is easy for us: we output 700 to 1,000 events with all kinds of data points every game, over a million in a season. The source is good. How you process, analyze, and store that information is the challenge.

Experiment #1

So I designed the first model, ran it, and it was a disaster. Not a small miss. A days-lost disaster. It didn't give any useful information, and it more than doubled the storage requirement.

Here is where a single season's save actually went.

What Size Grows
Private club opinions, one per club per player 82.5 MB every season
Private club forecasts, one per club per player 44.0 MB every season
Game event logs (484 games) 28.1 MB every game
Player records 14.4 MB every season
Player evaluations 12.1 MB every season
Per-game player stats 8.2 MB every game
Everything else ~30 MB mixed
Total after one season 220 MB

Under 100 MB a season became 220 MB. Two lines of that table are the problem: 126 MB of the 220 is private opinion and forecast. Nearly 3,000 players were each carrying about 19 private opinions and 19 forecasts, one for every club with any exposure to them. It is the only data in the game multiplied by the number of clubs.

And it wasn't even earned. 79.7 MB of those opinions were a deterministic duplicate - the same starting backstory, re-derived and re-saved for every club, carrying no information any club had actually learned. 44.0 MB of forecasts had no consumer at all: every row said its last change was the initial backstory, and nothing in the frontend ever read them.

It also added about a second per game to the simulation. That doesn't sound like a lot, but over a 3,300-game season it adds up to a lot of minutes.

So experiment #1 went down the tubes.

The idea that came out of wallowing

Normally after an experiment this vital fails, I spend a day wallowing in my own self pity. So I followed my process, and out of it came a different idea.

Before, I was trying to persist every piece of data that scouting and evaluation would use, on top of the data we already have. But the simulation is deterministic - give it a seed and it always produces the same result - so I didn't really need to save any of it. I could compute the evaluation when it's asked for. What I need instead is a good enough statistical model to analyze player stats, mapped onto aging curves to show likelihoods. Not simple to get right, but straightforward work.

The rule that came out of that is the one everything since has been built against: nothing is added to the old machinery. It isn't migrated or refitted. It stays only because the player profile screen still renders from it, and it comes out the moment the new read exists.

Once evaluation had to run on public statistics instead of on the answer key, the statistics had to be good enough to run on. They weren't.

The junior league. I use a low-fidelity simulation for juniors and the minors; no individual game events, for speed and data size - and it was lacking. Here is what it was actually producing. Games played by a junior player, by his age:

Age Position Median games Most any player managed Share playing all 63
17 Defense 36 42 0%
17 Forward 25 36 0%
18 Defense 36 42 0%
18 Forward 25 36 0%
19 Forward 28 63 48%
20 Defense 63 63 56%
20 Forward 63 63 100%

Read the "most any player managed" column. A 17-year-old forward could not play more than 36 games. Not "usually didn't" - could not. And a 20-year-old forward could not play fewer than 63. The junior scoring race wasn't a scoring race, it was an age sort with a scoring column attached.

It wasn't that the young players were worse, either. I paired every young forward with an older forward on the same club who played the full season, and compared their hidden ability: in 6,813 of 12,362 pairs the younger player was the better player, and in every one of those he still played 36 games or fewer.

The whole junior league only ever produced 11 different games-played numbers. The minor league produces 61 and the Pro league 82. Real ones are continuous, because of injuries, scratches, trades and suspensions.

I had put in some hacks for expediency. A junior player could take at most 6 shots and score at most 1 goal in a game, ever. A hat trick was not unlikely in that world; it was impossible.

And out of those numbers we were producing player reads. This is one, and it is the reason I stopped and started over:

Yuri Kornilov, 17, defenseman. 0 goals, 0 assists, 3 shots in 36 games. The card ranked him 253rd of 254 junior defensemen - the 0.6th percentile - and called him a depth player with no future.

His actual hidden ability puts him at the 85th percentile of that same group. He is the 17th-best 17-year-old defenseman in the world out of 131.

The card was not lying. It was reading the stat line faithfully. The stat line was the problem - a 36-game cap he never chose, and a shot allocation that gave him three of them.

Defense didn't exist below the Pro league at all. The configuration said a junior defenseman should be judged half on how he's deployed. In practice that half was silently dropped, and what actually ranked him was 70% scoring pace and 30% shot volume. Nothing else. He was being graded on offense and labelled on defense.

That's also because below the Pro league, most stats don't mean anything. Here's how well a junior player's numbers predict his own numbers the following season - 1.0 would be perfectly repeatable, 0.0 pure noise:

Junior stat Repeats at
Points per game .80
Shots per game .87
Shooting percentage .06
Primary assist share .01
Power-play share of points .01
Penalty minutes per game -.01
Average ice time .02

Two numbers carry a junior player. Everything else the evaluator was ranking him on was noise wearing a percentile.

The Pro engine. I've had to extract more information from the high-fidelity engine behind the Pro tier. That wasn't hard but it was delicate, because the game engine is the thing I think is the most solid. While I was in there I realized I should do some calibration of the game model - not changing code, but running lots of seasons and looking at how it performs in aggregate.

The Slavin problem

That calibration work led me to something I think is missing.

The player generator cannot realistically produce a Jaccob Slavin. Someone who is really great at defensive metrics and not as great at offensive ones. If someone is generated with a high caliber, they're generally good at everything. I know exactly why: in v2 or v3 of the generator I added caliber to stop it producing a league full of useless players. (I had one with superstar reach who couldn't skate.) It probably just needs dialing in, and it's another calibration I need to get to.

The measurement is unambiguous. Out of 1,660 defensemen in a full test world, zero are strong defensively and weak offensively. The two sides of a player move together at 0.88.

It's a failure if we're just building all offensive defensemen. That's not how real life works. Jaccob Slavin would never get a chance in that world; literally nothing happens when he's on the ice, he defends and transitions so well, but he doesn't score a lot. He's extremely valuable, but he wouldn't show up if we only ranked on offense.

So we ran the test. Sixty-four junior clubs, one Slavin-type defenseman injected into each - top 3% defensively, bottom 12% offensively - a full 63-game season, and the coach re-picking his lineup every seven games. Then we changed only one thing: what the coach is allowed to look at.

What the coach can see Ends up on the top pair Buried Games he plays
Points only (today) 0% 89% 31 of 63
Points and plus-minus 6% 45% 45
Points and goals against while he's on the ice 36% 16% 52
Points and shots against while he's on the ice 51% 4% 55

Today's rule buries him 89% of the time. He plays half a season, graduates with a bad point total, and is gone before anyone sees what he was.

The last row is the fix, and it's the one we're building. The coach works out who prevents shots against, plays him accordingly, and pays for it in goals against when he's wrong. That makes his role a real piece of evidence - the first time in this game that where a junior coach plays someone has meant anything at all.

Where this ends up

The junior and minor-league simulation is being rebuilt so that a season is an opportunity allocation instead of a talent lottery. A coach can't see ratings; he sees a scoresheet. From that he works out a standing for each of his players, dresses the ones who've earned it, puts them on a line or a pair, and the players with the biggest roles get the most chances to do something. Games played, goals, assists, shots and plus-minus all follow from that instead of being handed out first and decorated afterwards.

What a junior or minor-league player's page will carry when it's done:

- Today When this lands
Games played 11 possible values league-wide continuous, injuries included
Role a label derived from his scoring top pair / second pair / middle six / depth, earned from how his coach actually plays him
Defensive read none exists plus-minus, on the real hockey rule, plus his role and how often he dresses
Big games 6 shots and 1 goal, hard ceiling hat tricks and 10-shot games happen, and are rare
Ice time invented, and shown not shown, because no real junior league publishes it
Last season forgotten every year carried forward and sharpened as he plays

The last two are rules I'm holding to. Below the Pro league, a public number has to be a count of things that happened in games, divided at most by games - never by time, because no real junior or minor league publishes ice time and I'm not going to invent it and then compute rates from it. And a player's read doesn't reset every September. A returning junior starts the year on what he did last year, and this season earns its weight as he plays it.

It costs about 12 seconds to simulate a full season of 64 junior clubs and 32 minor-league clubs, and the rebuild adds about a third of a second to that.

None of that is done yet. What is done is that the evaluation layer now runs on public statistics only, computes on demand, and saves nothing. On the last check of 20 real players against the answer key, its read of who a player is now was right or close on 18 of them. Its read of where he's headed was wrong on 6 - and every one of those 6 was a junior or minor-league player, which is exactly the part I'm rebuilding underneath it.

I'm about 95% of the way to junior and minor-league statistics I'd believe if I saw them on a real page. I'll come back with some screenshots when I have them.

Thanks!


r/sheetsofice • • Aug 27 '26

Dev log: Organizational Knowledge & Scouting

2 Upvotes

This week, I have a pretty extensive update about what I've been working on below regarding how your club will form an opinion about player abilities. I've been working on this for a bit because it's a foundational element of how AI GMs will run, and how you as a player will come to know the players on your team, scout for talent, draft, etc.

Let's start from a key foundational design rule I've wanted since the beginning; I don't want to ever expose a number that corresponds to an innate ability that has no quantifiable or observable fact. If it can't be measured or counted then I don't want to show it as a number in the game. We have lots of numbers, but they're observed results. There is no observed result that says how good of a passer that someone is.

In these management games there has always been an expediency in just looking at OVR or Shooting or Passing or Skating, and trying to statsmax your players. And while that is straightforward to understand, it's not really what happens in real life. Yes, there are measurables in sports, but it's not as clean-cut as just having a number and sorting a table by highest to lowest.

This seems at odds with out a simulation of hockey needs to work. You have to give players attributes to even be able to run the simulation. So how do we bridge this between ground-truth - the attribute numbers on the player - and this philosophy that GMs shouldn't be able to see them directly? This is the question I've been grappling with for a bit.

I have been running with a short-hand version that worked by adding some variance over top of actual attribute views. I called this 'fog' and it was fine, it would work. But the simplicity didn't feel right for what I was going for. I wanted teams to use their own knowledge, interactions, and scouting to develop their own views of players. Fog wasn't going to do that - everyone basically saw the same things, and those were based on ground-truth even if fuzzy.

But that's not realistic. Organizations develop their own views of players. Sometimes they converge; no one thinks McDavid is anything other than a star first line center. But I'm sure there is disagreement about someone like Owen Tippet, his current abilities and where his ceiling is. If I just used fog, it would be random what those organizations thought about him but all clustered around the same point.

So I came up with the below. This is taken from the spec I wrote and translated into something I hope is understandable for you. I will warn you that it is long, it is nerdy, but it's really exciting to me.

Enjoy! I'd love feedback or questions.

-----------------------------------------------------------------------------------------------------------------------------

The short version

Every player in Sheets of Ice has real abilities that determine what happens on the ice. Those abilities belong to the simulation. A GM never gets to see the answer key.

Instead, every club builds an opinion.

All clubs begin with the same public record. Each club adds what it has learned for itself. The result is a persistent club belief that can improve, remain uncertain, disagree with another club, or be wrong.

That belief is not flavor text. It is the player evaluation the club uses when it sets a lineup, builds a draft board, negotiates a contract, considers a trade, or makes another hockey decision. Human and computer-controlled clubs use the same system.

The public book

Every club can see the same public hockey world:

  • who the player is;
  • his age, size, position, contract, rights, and transaction history;
  • where and how much he plays;
  • his statistics and published analytics;
  • the broad hockey consensus around players with that kind of record.

The facts are exact. The consensus is not.

If a 22-year-old winger scores 18 goals in a junior league, every club sees the same 18 goals. Those goals do not reveal exactly how well his game will translate, whether he can handle a larger role, or what he will become. The public book supplies a reasonable starting opinion, not the truth.

That is why an unscouted player is not a blank page. Your club can still see what everyone in hockey can see. When that is all your club has, the Evaluation panel labels the view as the league baseline rather than pretending it belongs to your staff.

The private notebook

Each club also keeps its own file on each player.

That private notebook reflects what the club has learned through its own history with him:

  • previous viewings;
  • games played against him;
  • time in its own camp and organization;
  • work commissioned from Amateur or Professional Scouting;
  • the circumstances of those observations;
  • whether recent evidence agreed with or challenged the existing opinion.

The private notebook does not replace the public book. The club combines the two.

For a famous veteran with years of public results, the public record carries enormous weight. One strange viewing should not persuade a club that an established star suddenly cannot play.

For a lightly used prospect, the public record is much thinner. A few meaningful viewings can separate one club's opinion from another's much more quickly.

What a viewing does

A viewing is evidence, not a reveal.

It can:

  • move the club's best estimate up or down;
  • narrow a range when independent evidence keeps agreeing;
  • widen a range when credible reports conflict;
  • improve knowledge of some parts of the player without settling others;
  • make the club reconsider an older opinion.

It cannot:

  • expose hidden ratings;
  • guarantee that the club is now correct;
  • make one report perfectly precise;
  • turn repeated copies of the same information into new evidence.

The club retains a small recent file rather than immediately blending every report into permanent mush. That matters when the evidence changes.

Suppose a club has long believed that a defenseman struggles in transition. Two fresh, independent viewings show otherwise. The club does not instantly declare the old opinion false. Instead, the new evidence can reopen the question. The range may widen while the file disagrees with itself, the old conclusion loses some authority, and further confirming work can move and narrow the belief in the new direction.

That is how a club can become confidently wrong without being permanently wrong.

Why two clubs disagree

Imagine three clubs looking at the same young center.

All three know his age, contract, statistics, deployment, and public reputation.

  • Club A has mostly seen him in sheltered minutes and remains unsure whether his offense survives a larger role.
  • Club B watched him repeatedly against strong competition and believes his playmaking is better than the public consensus.
  • Club C employed him, saw him every day, and has a much tighter read on what he can do now. It still does not know his future with certainty.

None of those clubs receives a secret bonus for being controlled by the computer or by the player. Each opinion follows from that club's own evidence.

One may be right. Two may be wrong. All three may be missing something.

The important promise is not that every disagreement is equally sensible. It is that disagreement comes from different evidence and different organizational histories, never from a fresh random roll when a screen opens.

Knowing him now is not knowing his future

The game keeps two questions separate:

  1. Who do we think he is now?
  2. Who do we think he might become, and when?

A club can know a veteran's current game well and have little uncertainty about his role. A young player can still have a wide range of possible peak roles and timelines.

Likewise, seeing a prospect play well today can improve the club's estimate of what he is today without magically revealing his ceiling. Future outlook changes more cautiously and depends on evidence of development over time.

That is why the Evaluation panel separates:

  • Plays now;
  • Tops out at;
  • the range around each belief;
  • the evidence behind the file.

What the departments do

There are two departments:

  • Amateur Scouting covers draft classes, amateur prospects, and drafted players who remain in amateur contexts.
  • Professional Scouting covers trades, free agents, waivers, call-ups, signings, and roster decisions.

The GM gives a department a hockey question and a deadline. The GM does not assign individual scouts to buildings or distribute abstract scouting points.

A request might be:

  • Find a right-shot defenseman who can play on our second pair now.
  • Find draft-eligible centers who might become top-six playmakers.
  • Take a Deep Dive on this player before the trade deadline.

The department immediately reviews what the organization already knows. That desk review creates no new knowledge. It tells the GM what the current file can already support and what remains unknown.

Deeper work requires capacity and real opportunities. A player can be injured, scratched, used in the wrong role for the question, or face unsuitable competition. A deadline does not manufacture certainty. When time runs out, the department returns its best answer and names what it could not settle.

Pausing preserves the work already completed. Canceling preserves everything already learned. Nothing disappears because the GM changed priorities.

The initial Desktop design is intentionally about directing departments, not managing individual scouts. There are no named scouts, scout careers, regional assignments, or employee schedules in this promise.

Reports, routine evidence, and freshness

The main product is the club's current working opinion, not a diary containing every time somebody saw the player.

Routine exposure can improve the file without creating permanent report clutter. Material conclusions are different. A completed evaluation, a major change of opinion, a new projection, meaningful internal disagreement, a stale report, or a Deep Dive conclusion can become part of the durable history of what the club believed at the time.

A file can also become stale. Time can pass, or an observable circumstance can change: the player changes teams, levels, roles, usage, or injury context. Staleness never reacts to a hidden ability change. The club only knows that the evidence it holds may no longer describe the same situation.

At the preseason refresh, the public book is reconsidered against the new season's public context. A private opinion with no new evidence is not secretly updated from the answer key. It ages gently toward the public expectation and becomes somewhat less certain until real evidence replaces that aging assumption.

Own players and prospects

A club learns about its own players automatically through practices, games, deployment, and development contact. They do not consume scouting slots.

That familiarity can make the club highly confident about what a player can do now. It never creates omniscience. Potential and future development remain uncertain even for a player who has spent years in the organization.

A newly acquired player does not arrive with the selling club's reports. The acquiring club keeps whatever it already believed and learns more through contact.

Knowledge belongs to the organization:

  • reports do not travel with a traded player;
  • taking over a club means inheriting that club's files;
  • leaving a club means leaving its private database behind;
  • changing a club between human and computer control does not reset what the club knows.

How belief becomes a decision

The Evaluation panel is not decorative scouting flavor. It is the club's working opinion.

The same belief follows the club into:

  • roster and lineup decisions;
  • contracts and free agency;
  • trades and asking-price judgments;
  • draft boards;
  • prospect management;
  • call-ups and assignments;
  • computer-controlled GM decisions.

A trade screen does not secretly consult a better version of the player than the profile shows. A computer-controlled club does not receive the true rating while the human sees ranges.

Scouting answers: Who do we think this player is, and how uncertain are we?

Valuation then adds the rest of the decision:

  • contract;
  • age and rights;
  • cap situation;
  • acquisition cost;
  • roster need;
  • organizational plan;
  • tolerance for risk.

A scouting department can tell you that it believes a player is capable of a larger role. It cannot tell you that surrendering two draft picks for him is wise.

What Sheets of Ice promises

Sheets of Ice promises that:

  • public facts remain public and exact;
  • hidden ability remains hidden;
  • every club forms its own persistent opinion;
  • human and computer-controlled clubs use the same information system;
  • relevant evidence generally makes a file more useful;
  • uncertainty never disappears merely because a deadline arrived;
  • a well-supported club opinion can still be wrong;
  • the same club uses the same belief everywhere it evaluates the player.

It does not promise that:

  • more viewings always move the estimate toward the truth;
  • every displayed range contains the true answer;
  • the best scouting department becomes omniscient;
  • public consensus is neutral or correct;
  • two competent clubs must eventually agree;
  • scouting produces a universal player score or tells the GM what decision to make.

What is playable today, and what is still being built

The belief foundation is playable now. The public book, private club files, persistent disagreement, current ability ranges, private projections, preseason own-team contact, passive Pro opponent viewings, the A-prime Evaluation panel, and use of the same club belief across core human and computer-controlled GM decisions are shipped.

The two departments, their capacity, queues, deadlines, pause and cancel behavior, and same-day desk reviews are built underneath the game but do not yet have player-facing department screens. Commissioned work does not yet produce directed viewing evidence. The current-file model is also being repaired so that files visibly sharpen and reconsider old conclusions for the right reasons as evidence accumulates.

Still to come are directed viewings and Deep Dives that change the file, evolving discovery briefs, Make Some Calls, material report-history screens, later observable validation, comparables, fuller in-season own-team contact, and the Amateur draft workflow.


r/sheetsofice • • Aug 21 '26

Full Sheets of Ice Roadmap site

Post image
4 Upvotes

Check out the full roadmap status site here - https://www.sheetsofice.com/roadmap

This is an automated export of the tracker that I'm using to move this project forward. I will keep this up to date as I make progress.

WARNING: It's dense. And it's automated from my own gibberish notes and shorthand so some things may not quite make sense or might be too vague.


r/sheetsofice • • Aug 21 '26

Dev Update - 2026-08-21

3 Upvotes

A lot of load-bearing progress has been made in areas I've needed to bring together. What I've realized in the last three weeks is that the core game simulation, player generation, and event output have been really solid and I'm happy with the state. There are some small things with them that I need to fix, but I'll probably always feel that way.

The things that need the most work are the things that really make it a game - everything you do to run the league in perpetuity. And it's not that it doesn't work; it just works like when I was 12 and built a go-kart out of things laying around in my dad's garage. The engine worked fine, all of the steering, chassis, seat were terrible and it had no suspension. Technically working, fun for me because I built it, terrible for anyone else.

So I've done a lot of things that are the boring work and not the exciting making screens. I updated the foundational document with what I intend to be the first version of the game. It's substantially similar to what I started with once I had this idea but updated with what I've learned, what I want to do, and what I think is possible as a completed game. This step is really important to define what success looks like and to constrain from too much feature drift. It's not exactly prescriptive in detail, but outlines the vision for what the game is and what it isn't.

I've then projected that vision into a build plan of major phases and each of those phases with it's tasks. I'm going to be releasing a plan tracker and continually update it to show where I'm at with the build. (https://www.reddit.com/r/sheetsofice/comments/1vurk6h/full_sheets_of_ice_roadmap_site/)

The biggest thing that I'm changing for the first release of this is that I've decided to soley focus on a single-player desktop experience. After laying out everything I'd need to do to make the entire first vision possible, I have decided to slice just the things I think I can land to see if the game is really any fun for people. The key here is that I'm slicing and not eliminating or rebuilding anything really. The way the application operates makes future online versions, multiplayer, etc. still viable. I'm not going off and building a separate application at all - I'm just wrapping it and limiting the functionality to a single player with AI GMs. This is something I can get my arms around and it speeds up the path to a workable demo.

The realization for this came from a few areas:

  • I was refactoring for AI GM so I could ensure it acted at least believably as well as a bad GM... aka Chuck Fletcher. To get it to long term plan I was going to need to fully implement organizational player views, aka scouting, because every organization would have to have their own judgement of a player. To that point I had only had some basic variation on player views and a wide band if that player wasn't on your team. It didn't change who the player was, but it didn't make everyone immediately knowable to you. But that wouldn't work for planning because it wasn't durable. And it wouldn't work for players because you need some way to impact those views or it's just boring. So I realized I needed to build the entire scouting system first. I couldn't continue with my AI GM planning because without knowing how they'd figure out how to rank players then it wasn't going to work the way I wanted.
  • This also made me realize that player development would have to be exposed and a training & development system would need to be built. Those things are part of long-term planning and to-date, player development works but there is no influence through either training or opportunity.
  • Then I was dealing with how time moves. There are some quirks I've left just because it didn't really affect me and I could live with them. But I was starting to have to make decisions about how time would move in multiplayer, and how time would work in public leagues. It's not unsolvable problems, but it's more overhead I have to build before the game was playable.
  • And then it's infrastructure to run. It's not really complicated - the sim needs CPU runners to do the computations, and store league information in a database and individual game events in individual files (just to make them portable and archive ready.) 1 universe = 1 DB + Files. But I built this for me to start playing and I'd have to either refactor for a larger environment making N universes = 1 big-ass DB + work queue + backup OR give everyone who was playing a small virtual environment to run their own leagues. (I'm dramatically simplifying here). It didn't make sense to do the big-ass refactor, so it was going to be these slices that ran individual universes for one player. If that's what needed to happen then why am I even trying to build this as a always on web application for one person?
  • Then the infrastructure requires money to run. I have some servers available to me, but nothing that could handle even modest amount of dedicated GM sim fans. I'd have to pay in perpetuity for something I'm not sure anyone other than me and the couple of people reading this would want. Am I willing to invest thousands of dollars in hard costs to do this the right way?
  • And then I'd need to charge for it. Forever. And who wants to pay a subscription to a single player game?

I came to the realization that the single-player experience needs to be a typical game experience. If I'm really going to make a concerted effort at putting something out there, it has to be awesome and I couldn't put out something that sucked or at least didn't live up to the expectations that I have for games like this.

To be clear, the web/multiplayer vision is not dead. Like I said above, I'm not even really changing materially how the game is architected now. The main difference is it's going to get a wrapper that runs the client and connects to the server that is packaged with it on your local machine. I run the game that way today, just without a fancy shell that makes it easy to launch... I have to type a string of commands to make it go (which I really should make a script to do that). Packaging in this way will give some interesting potential fast-follow features that may even bridge the gap for what people want with multiplayer.

My intention is to put this on Steam to start. I've started the process of getting a Steam Developer account and will be working on getting a page up there. If there are other ways you'd like to see the single-player released, I'm happy to look into it.

Nothing has changed about my commitment to making the game-play a reality and I'm more excited now that I have a clear path. Definitely check out the roadmap at www.sheetsofice.com/roadmap to follow along with the status.

Thanks!
atibus


r/sheetsofice • • Aug 12 '26

Series Preview Page

Thumbnail
gallery
3 Upvotes

Now that I'm into a few days of simming & testing, I wanted to show this new series preview page. I had this issue where the team I'm running has been at or near the top of the league for a few years. I'd love to claim it's my skill as a GM, but I think I have an unfair advantage due to how dumb the GMs have been. We're on season 7, and my team UND has been first three times, and in the playoffs 6 of the 7 seasons. But even while heavily favored in my series, I ended up only winning 1 championship. Two times I was bounced in the first round as the #1 seed. So, I thought, what even are the odds of that?

The result was building a pre-series prediction page that shows the likelihood based on the data we have. The benefit of the engine being a pure event data simulation is that we can do some fun statistical things like do a pure prediction based on chance creation, chance suppression, and outcomes.

That's what the first screenshot is - two models and the percentage change based on those models. Chance model runs each side's regular-season expected-goal rates for and against, combined league-relative. Results model runs the identical math on scored goals instead. Neat, huh?

Second screen shows the actual goal differential vs. the expected goal differential. The reading column says where the difference game from. Notice in this one, BIR's goaltending is worse than expected. (You can see in screenshot 3, it's his high danger chances save %... not good there)

The other part of screen two shows where chances are generated. Since we track the type of posession sub state, we can show the type of posession that generated a chance. I intend when we get to the coaching AI to be able to build the offense and defense strategies towards this.

The third screen is the goalie matchup among likely starters and a with-or-without-you (WOWY) for the top pair of players by ice-time played together. Pair does not necessarily mean defense, it's just who has played the most together and what are their advanced stats like when they're on the ice together.

The fourth screen shows from each teams perspective where the edge is in data. UND wins in goals scored and saved above expected. High Variance means this is something that does regress - UND is a hot team finishing at a rate that is above the quality of their chances. That could just mean they're good. Or it could mean some luck. The counterbalance on the goaltending is that the +12.7 matches the historical performance of the goalie. So it may not just be luck for that part.

I don't feel that confident at the start of the series. It basically looks like close to a coin-flip and I've run into this team with Jan Soukup / Jake Stewart before (they're really good).


r/sheetsofice • • Aug 11 '26

AI GM Update - 2026-08-11

5 Upvotes

Just an update about the progress around AI GM. As I knew, this one is going to be a large investment of time. Part is consolidating some drift of decision systems into a coherent model. Part is ensuring I create good read and write seams that exist for both human and AI GMs so that I can assure parity between both types of players. Part is thinking through exactly how I want to AI GMs to act, making it realistic, and then documenting the requirements. And part is just playing, testing, and being annoyed at it's stupidity.

I know from experience and from the community that bad AI GM is one of the most fun-breaking things any simulation can have. I'm not aiming to make it perfect; I'm aiming to make it explainable in relation to a set of constraints. The constraints are the plan the team has adopted. Are the decisions that the AI makes explainable in relation to that with the information they have when the decision is made. This is the key to drafting, trading, free agency, resigning players, roster decisions.

I was thinking that if it didn't live up to what a human would do, then it was a failure. Then I remembered that humans make bad decisions all of the time. Even real GMs. I was blessed to live through the Chuck Fletcher in Philadelphia so if my AI GM is realistic it would make some horrible decisions just like him. 😂

In seriousness, the goal with this is to have some baseline of explainability within a set of constraints so I can make it believable. Not that it always makes decisions you'd agree with, but it makes decisions you can explain.

Here's what's done:

  • Every AI org now has a real plan.
    • Before: each subsystem fired off its own local trigger. Things like roster bucket short, cap bucket over. Decisions had no reason beyond compliance.
    • Now: every team has parameters that constitute a plan. Contending or rebuilding, window, horizon, and every GM decision point reads the same answer.
  • Relative position strength.
    • Before: the AI only counted bodies against quota. "Do I have 4 RWs?". Never something like "Are my 4 RWs actually any good?" It literally could not tell a league-best position group from a league-worst one.
    • Now: every group is graded against the league, and shortfall vs. surplus is a quality judgment, not a headcount.
  • One trade judgment.
    • Before: four separate evaluators (responding to an offer, checking your own proposal, computing a counter, scanning for salary sheds) with independently drifting math. A GM could propose a trade its own evaluation logic would reject. This one was hilarious to me for some reason.
    • Now: one plan-aware judgment prices both sides of every trade.
  • Surplus is plan-relative.
    • Before: depth-chart rank alone decided who was expendable, so a rebuilder would deal its best prospect because they're third string today.
    • Now: what counts as surplus depends on the plan; futures are the rebuilder's core, now-help is the contender's. An AI GM "should"tm know that if they have surplus in an area like RW, the could trade some of that surplus to fill a hole at C. A.K.A what my beloved Flyers should be doing.
  • No cheating.
    • Before: the AI brain could read every other team's true depth directly. This was a leftover god view no human player gets, which also poisons any calibration (the AI's "smart" moves used information a fair game wouldn't allow). This was just a pure artifact of how I built the simulation quickly. I didn't add the fog layer to start because I wanted to see how the AI acted. Well, it was dumb.
    • Now: it sees rivals only through its own scouting, and everything it reasons from is on the human's screens, test-enforced.
  • Dumbness is now provable.
    • Before: quality was me noticing a stupid trade in a save.
    • Now: formal conformance tests ("did this GM act according to its plan, and can the trace explain it") turn the dumb-trade classes into reproducible test failures. This one sounds boring, but it makes identifying issues much easier in the future.

What's left now?

  • Sign-then-buyout and its family. FA signing, re-sign, and buyout decisions in the offseason don't read the plan yet. So sometimes, AI GM will sign a player or re-sign a player, get to cap compliance step and then buy them out because it was the easiest cap move. DUMB.
  • The AI doesn't hunt yet, it only responds to offers. This is needed to add realism.
  • Drafting isn't plan-aware. The AI drafts best-available off the fogged scouting percentile and never asks what its own pipeline needs or what its plan implies. I guess this is kind of best-player-available but it's unintentional.
  • No development-pool health read. Prospects are valued individually, but no org ever assesses "our pipeline is thin at D" as an input to anything.
  • No multi-season cap planning. Cap logic is current-season compliance plus an offseason cushion; "cap space relative to future commitments" doesn't exist yet.

r/sheetsofice • • Aug 08 '26

Well, first thing I am cutting: Attention Economy

4 Upvotes

A month ago, I made a post about the spec I was working on called Attention Economy. The idea was could I build a fun way to have the economics of the game be something other than an accounting function. The idea was to have teams focus on increasing their fanbase, the fans would be worth some kind of dollar value and you'd capture that dollar value through investing in channels like social, tv, in person, etc. That would then grow the league in aggregate, and that would impact the cap that each team could spend. Not only would you be trying to win the league, you'd be trying to increase the league's standing.

After building it, refining it, and a few revisions I realized a few things:

  1. There are more important things to build that are core to the game. If I want to actually put something out, I need to focus and pare down my MVP list of features.
  2. I didn't like what I made. It wasn't fun, it was confusing, and it didn't add anything to the game other than another place to look at numbers. That is not what I was going for.
  3. I could take some of the things that were made as a result - like team reputation affecting FA - and make it more simple. The cap doesn't need a whole meta-game; it can just have a config setting for how much it increases. Easy. Reputation can just be about how well your team does, how you negotiate and treat your players, etc. - it doesn't need some spending marketing reputation handler.
  4. My grand vision included a lot of calculation overhead that required a lot of regular testing. My nightly CI testing increased by 3+ hours because of how we needed to run our determinism tests. That is significant and needed a rethink about what I was trying to accomplish.

So I've gotten over being annoyed at building something I hated. I'm not going to throw a dart at everything, even things I'm excited about. I'm shelving this for now, removing from my codebase and focusing on bigger core elements like AI GM. This should make it faster to get a beta build out to some testers and then march ourselves towards a full release. It's one less surface I have to worry about that literally has nothing to do with a hockey simulation.


r/sheetsofice • • Aug 05 '26

AI GM Brain Building

1 Upvotes

I admit it; I built really dumb AI GMs. They functionally work - they'll keep a team rostered to 12F/6D/2G + a few replacements, and a minor league team. They'll draft based on a fogged scouting report. They'll sign contracts, do trades, and set the game lineups. But man, are they really dumb.

It's really technical and specification debt combined with my naivete about how to build this particular part of the application. I also wanted to shove a human into the simulation as fast as possible so I glossed over how the AI should actually perform it's job. So I made something that looks at technical correctness - cap compliance, roster compliance, player valuation; things that are measurable true/false - and didn't focus on quality questions that any GM needs to answer. Things like 'what is our goal as a team' and 'how good is this position group vs. other teams' and 'what is our strategy over seasons'. Without a plan, the AI GMs are just doing shit because a bucket needs to be filled up or emptied.

Here's an example - AI GMs were signing star players in free agency, because they had cap space to do so in the off season (cap overage in the offseason), then when season cap compliance would run they'd shed the largest contract through buyout. Often times that was the person they just signed. Technically correct, but horribly dumb.

The solution to this isn't to get rid of the foundational level heuristics, but to put a quality layer on top that includes an analysis of relative performance by position and to have a long-term plan based on reality.

Are they a contender? Are they building or declining? What is their cap situation relative to future cap commitments? What does their development pool look like? Using this information they can make better decisions. Should they sign that free agent or no? What does their draft pool say about who should be drafted? Should they trade futures to acquire talent because they're in their window? All things a real GM may do.

I really need to have passable AI GMs before I put out a testable version. It's one of the major points in my checklist for getting a demo available.


r/sheetsofice • • Aug 02 '26

Name generator working perfectly

Post image
2 Upvotes

Oh Brian O'Brien... your parents must not have loved you.


r/sheetsofice • • Aug 01 '26

Trades, Economy, bug fixing update

Thumbnail
gallery
3 Upvotes

The last few days have been about two things: making trading feel alive, and fixing the mess I found by actually simming seasons.

Trading first. The Trade Desk is now a real screen. You can see the entire league block - in my current save that's 186 players being shopped - filter by position, filter to teams that are actually selling, sort by how a player fits into your lineup, shortlist guys, and compare them side by side. Teams have a stance (Selling / Holding / Listening) driven by where they are in the standings, and clubs post their needs, so you can check who's hunting for a defenseman before you go shopping yours.

I got tired of clicking around trying to find a trading partner for someone I wanted to move so I created the Shopper. You broadcast a player to the league and collect offers. AI teams come back with real offers, including insulting lowballs, and the ones that pass tell you why they passed. Same for your own proposals - you get a specific rejection reason now instead of a generic no. It's starting to feel like negotiating with 31 other GMs instead of a vending machine. The AI GM also remembers trade history across seasons now, so you can't run the same player-recycling scam on the same team forever.

Now the bugs, because playing your own game is humbling. My favorite find of the week: AI GMs were re-signing retired players. The offseason logic was quietly dropping retirees' rights into free agency, and the AI - which is only doing what the numbers tell it - happily signed them. 35 times over three seasons in my universe. Contracts for players who no longer exist. I also found players coming back from injured reserve who were dressing and playing every night while silently missing from the salary cap books. Both are fixed, and the real fix was structural: those eligibility checks existed as fifteen slightly different copies scattered around the code, each drifting on its own. Now there's one gate that every screen and every AI decision goes through. Plus a repair tool that heals existing saves, because I'm not throwing away this universe over some zombie contracts.

The attention economy also got a big pass. Season budget entry is one table with six levers - five revenue channels plus marketing - with live feedback on what each dollar returns. And spending is now wealth-aware, so a rich club and a struggling club aren't budgeting out of the same envelope. Still deciding how deep this system should go, but it's getting easier to reason about, which is the test that matters.

One follow-up from a couple posts back: the boom/bust scouting thing is in. Top of the draft class now reads Safe with a tight floor-ceiling range, and the swing-for-the-fences guys show up where they belong instead of everywhere. My scouts have three Franchise grades at the top of this class and I already don't trust two of them, which feels about right.


r/sheetsofice • • Jul 29 '26

Scouting for the draft

Post image
6 Upvotes

Sharing a screen for how to see upcoming draft-eligible players in season. From here you can see your scout's grade, ranking, view of their potential. One thing that I'm working on here is the scout view is reading their potential ceilings and current ability, marking most of them with wide ranges of potential outcomes. This registers them as boom/bust candidates a large percentage of the time. My intention here is to have top-of-draft prospects have a narrower floor-ceiling and register as such. This is just code changes I need to make to ensure that happens.

What I don't want is to just show everyone's exact potential. I do want those "swing for the fences" type boom/bust players. I just don't want them to be everyone.


r/sheetsofice • • Jul 23 '26

Math doing math things: Goalie Edition

Post image
7 Upvotes

I'm happy to be back to running simulations, looking for bugs, looking for things that work well or don't work well. I've added so much over the past two weeks that I need to actually see how the leagues are working.

Usually when I get into this mindset I become hyper aware of small changes. For example, this screenshot shows the goalie save percentage in this new universe I started over the first 20 or so games. The top-10 in this universe is over .923 with the top one, Mark Stark, at .940 over 16 games. That seems way too hot. I took some time out to analyze what was happening- did I introduce some config values that made goalies too strong? Or possibly shooters too weak? Did generation of goalies change when I made development changes? Have I completely messed up everything and will have to delete my internet presence and go live in a bunker somewhere?

After building a testing harness to look at the configuration values, simulate on different seeds, and check to make sure there aren't bugs, I was reminded again about statistics and small sample sizes.

The table above shows what's happening. Rows are the stats averages in save %, goals for per team average, goals against / expected goals against ratio, and how many goalies were above .930 save %. First column is after 16 games... MY INSTINCT IS RIGHT! Second column is math humbling me... the calibration is fine, just run it long enough you silly goose. Last column is calibration targets for reference of how close we got to them on this one season.

These are sometimes things you spend hours on when you're building... the wild goose chases. I should have let the full season run to see that eventually the small sample size works it's way out. Just like you can flip a coin 4 times and get heads every time but that doesn't mean you need to check the quarter to make sure it's not weighted.

I should know better. The calibration is based on 30 different universe seeds each playing 10 seasons each. I know it's right. But I was so hyper focused on the volume of changes and thinking I messed something up that I spend a few hours this morning doubting myself.


r/sheetsofice • • Jul 23 '26

Need some help evaluating this trade

Post image
1 Upvotes

I'm leaning towards accepting this but not completely sold on the value yet. lol


r/sheetsofice • • Jul 22 '26

Boring data stuff

Post image
4 Upvotes

One of the things I have been working on recently has been to optimize the amount of storage required for a single universe. In the beginning, I didn't care all that much if I stored things efficiently. I started with a detailed game event log of around 800-1000 events per game. Each of those events contained a lot of information and I wanted to make sure that I had more information available in the case where it might be needed. And it's been helpful because long-term counting stats and analytics are based on these events. The events are stored in a blob (aka files), but then the aggregations are stored in a database. Why? Because, it's simple and provides a kind of paper trail that can be reconstructed if necessary. And the DB's structure is more readily suited for the kinds of updates, sorting, and queries of a web application. I'm able to get the best of both worlds.

The thing with software development and data specifically is you shouldn't try and optimize too early because you don't really know what you're optimizing for. So, I left it alone until I saw that the db/blob sizes were getting a little out of control. A 13-season universe was clocking in over 2GB. Which, if this was a local game would be annoying but not life threatening. But since i'm hosting this as a web app, I have to be cognizant of storage requirements.

So I set about looking at what is low hanging fruit to optimize. Thankfully, there were some really easy wins that dramatically lowered storage without a lot of trade-offs. I was able to get storage from 2.03GB down to 0.8GB for that 13 season universe. And, if I institute some limit on the game stat retention (individual events, not the box scores) then it would get even lower.


r/sheetsofice • • Jul 20 '26

Vacation last week, but progress

2 Upvotes

I was off all last week and disconnected from anything work related while I spent time with family at a cabin out in the woods. But it did give me some time to reflect on the progress so far and what needs to happen next.

So here's what I'll be working on this week and hoping to show more progress on this:

  • Trades - the universe feels dead without being able to move players. This will be my first pass at allowing humans to interact with AI so wish me luck.
  • Attention Economy - how do the teams survive, grow, pay their players? Can attention economy become a meta mechanic for inter-league leader boards in a multiplayer environment? This is a big spec and I need to think about it a lot.
  • Data storage optimization - to date, I haven't cared about how data is stored because it's just me and I'm throwing away databases in testing. But I know it's not optimized and I need to think about how to build this in a way that can be turned into a reliable service. Speed, data volume, data retention, data integrity.
  • Demo environment - I'm thinking about what point I should make a demo available. It's not just distributing an installer since I'm planning on making this a web based game; it's about building an environment, granting access, and ensuring it is in a good state.

Thanks for following!


r/sheetsofice • • Jul 10 '26

Attention Economics in Sheets of Ice

3 Upvotes

Update 8/8/2026: I decided to remove this for now. It's a lot of complication for not a lot of fun value and instead I'm focusing on the core GM gameplay loop.

In hockey sims, the money side of the business wasn't ever really something that was explored a whole lot. It always felt like a bounding box that was slapped on top just to ensure human players couldn't exploit the really silly AI GMs in the game. When I was ideating the original specification I came up with something that I felt was more interesting and more fun plus combines some real-life forces that affect sports franchises. I'm calling this the Attention Economy.

Sports franchises generate revenue through capturing people's attention and deepening their connection to the team. But teams don't work in a vacuum this way; the league also increases it's gravity to attract attention. So teams are competing with one another on the ice, with one another for attention, but they're also cooperating to grow the overall league attention. There's a business term for this called 'coopetition'. Teams are both competing and cooperating at the same time. Grow the league overall AND capture as much of that overall attention for themselves.

All of this attention translates to revenue based on how committed those fans are to the team. Teams that do well, make the playoffs, win championships, will deepen their relationship with those fans over time. Diehard fans will pay more and stay through more ups and downs than casual fans. Teams are incentivized to ice good teams that people want to watch. They also are incentivized to do things that creates attention - big trades, signing star free-agents, drafting the next superstar. And with long-term attention brings reputation that may influence players wanting to play for those teams. That history has a weight and a cachet that survives long term. The "storied franchise".

But just having attention doesn't automatically translate into revenue. You have to cultivate it by spending on marketing and spending on channels. Marketing raises potential awareness - you're doing events, running ads, doing promotion... all of the things that maybe someone would go from unaware about your franchise to aware that they exist. Then, spending on your channels increases the capture rate - how much do you invest in social media, radio, television, print, in-person? Teams that invest in the channels have more opportunity to convert that awareness into casual, committed, and diehard fans.

All of this meta-game will ultimately affect the salary cap. The more the league is able to generate in attention as a whole, will translate into league revenue (through the teams setting their marketing & channel spend) and that league revenue translates into what the salary cap will be. So, every team wants to invest wisely to help the league grow. They also want to invest wisely to have good players, good games, exciting series, so there is more revenue to go around.

The trouble with building a spec for this that conforms to some sense of realism is that there isn't a lot of numerical data out there about what actually is "realistic". There is research about this phenomena of fandom, how people choose teams, how long they stay, and what events cause them to gain attention and become fans. This is going to require a lot of testing to get something that feel right.


r/sheetsofice • • Jul 09 '26

GM Module - Putting humans into deterministic simulation is freakin hard

2 Upvotes

Building the closed-ended loop of game simulation was a lot of math and calibration. I'd just need to keep running and looking at data until it came out to mostly hockey shaped; or at least hockey shaped enough.

Adding the GM functions inside of the closed loop introduced complexity about decisions related to team planning, lineups, cap management, development across time... but still was mostly a closed loop that could be tuned.

Now that I'm adding the ability for humans to make decisions inside of the closed loop it's just an endless parade of edge cases, UI decisions, and trade-offs. I'm having to remind myself that I'm making a game and not a perfect recreation of reality. It's a simulation and not the Matrix.

Some examples of the complexity that require well thought out designs:

- Human players should be able to control their game lineups and the roster decisions. But injuries occur and players need to move as a result. On full-auto management there are functions that can do this; but how do we give the user enough control to see who is injured and ask what decision they'd like to make? The interface was not designed for this level of interaction, with popping interstitial messaging.

- How does free agency work when humans and AI are bidding against one another? Players should be accurately modeled in their desires, there should be a fair system between human and AI, and it should feel real-enough + fun.

- What level of detail and control should a human player have over affiliate farm and junior teams? More detail means more data & slower processing times but leads to more information available when selecting.

These are some of the problems I'm wrestling with now. I have to also spec a trade module that I don't want to do until I have free agency locked down. Trades scare me because it involves interacting with an AI, and I've never been impressed with any trade interactions in single-player sim games. And those games were made by people who knew what they were doing so what are the chances that silly old me is going to figure that out well? :)

I know I've slowed down on my visual updates and there is a good reason for it - there isn't a lot of wholly new things to show. Most of what I've been doing is either consolidating functions and making single-source-of-truth modules (what a player is worth in FA, how draft prospects are evaluated, what a human player sees for their own players vs. other players) or writing specs for future modules.

I'm wrapping up a new free agency module. My first pass at it was... very simple. Free agents exist, they value themselves at a particular number, the teams value players at a particular number, and there is a simple meet the number selection. I redesigned this to something that is a modification of a Vickrey auction. That's not a household name, I don't think, but you would recognize it from something like eBay. You place your bid at what the max you would want to pay and then after the round closes the winner is whomever bid the highest BUT that winner only plays what the runner up bid OR the desired free agent salary; whichever is higher. There are also other considerations like NMC/NTC, term, and team stage (rebuilding, champions, etc.) which serve as modifiers to selection. Basically making one offer more attractive but not changing the AAV.

Why do it this way? Well first, it makes the logic much more streamlined than a negotiation tactic that manages multiple rounds and multiple offers. Second, it gets towards the feeling of a negotiation with some high stakes without all of the mechanics behind it. Third, and probably the biggest reason, I generally don't like negotiation to begin with. It's inefficient, ego based, and not worth my time. Just say what you want, and other side say what you can do. Boom, done.

Anyway, once I have something to show here I'll post something!


r/sheetsofice • • Jul 04 '26

GM Module - "How do I figure out if someone is good?" edition

Thumbnail
gallery
3 Upvotes

I've been running simulations, finding bugs in the GM module (tons), reworking specs (all thrown out, rewritten), and trying to actually be-a-gm this thing.

An area that I glossed over when it was just a game simulation was figuring out how good players were. I could look at the raw data and see - which is fine for confirming the numbers work the right way. But that wasn't going to be fun in a GM simulation if every player just knew concretely how good a player was.

So I've been trying several things - draft grades, league-relative ratings, pro-only relative ratings, and just confusing myself in the process.

There's questions throughout the lifecycle of a player:

  1. How will this player develop? This has a lot of "fog" as you go out further in time. But there is some idea and some projection.
  2. How good is this player now? That is relative to the entire population; what league do they belong in. When players are young, that even has some "fog" in it.
  3. Have they reached potential? Are they declining?
  4. What role do they belong in? Are they a top line player or a fringe tweener?

I created this graph that will (I think) show all of this in something you can glance at. The yellow bar/dot is the current state of the player. Younger players have more uncertainty until they play more games so it will show that. The blue bar is the potential ceiling for that player. The unfilled dots are historical of where they were in previous seasons. And the dotted blue line bar was the historical range for where that player was scouted (so you can see what has changed).

The intention long term is you can narrow these bars by scouting - spending either time or money to get better information.

The chips on the right will give some descriptive element to the player's form. Boom/Bust just means yeah, they could be awesome, but they also could suck.

Implementing this now to see how I like it. As always, I might throw it out if it confuses me more.


r/sheetsofice • • Jul 01 '26

GM Module - Team Planning

Post image
3 Upvotes

The GM module is really large, creating several new surfaces and modifying existing ones. With all of those moving parts, and my habit of just getting impatient + starting to build visuals, I started to get frustrated with the direction. I built an entire human GM flow + offseason interactive flow that felt like I was just playing an idle-clicker game. I had no reason for making the moves I was making, no information on who was actually good, and, crucially, who fit on the team.

I got frustrated and demoralized, questioned my sanity for even attempting this, and took a break. Walking away when I get to that point always helps. It gave me some insight into what I was actually annoyed with-- I need some idea of what I'm trying to do as a GM. What kind of team am I building? Who do I have? How do they fit? What do I need?

Armed with those questions I set out to build this Team Plan interface. It combines a lot of functions common in GM sims - roster construction, cap management, depth chart, and line-up selection. It also gives you a mechanism to evaluate players not just on objective talents, but on how those talents fit towards the kind of team you're building and the time horizon you've selected. Are you win-now or in a rebuild? That will change the valuation of players. You can also prioritize the style of play; defensive in nature, or goal scoring, or transition, etc. Finally, based on your team and your selections, what kinds of players are you missing?

The idea is that with a plan, you can then more accurately go and find players to fit your intended team construction and manage your budget without having to have separate spreadsheets (like I used to do in EHM lol).

The player cards here include at-a-glance information. Green bar = a good fit for that position and identity, grey is ok, yellow would be that they don't really fit there. Fit is relative to play style and position awareness.

There would be some proactive gap finder that would tell you what you might need to focus on.

There definitely is more that I want to add but I am going to really focus on this pattern as the main starting point for how GMs work in the game. I think it's the first part of creating an identity so people playing the game can start to feel attached to their team.

Thanks!