Login or Register

Admin Panel

Create Game
Manage Users

    Personal Sandbox

    Multiplayer Games

    Rules

    Game State

    Nomic

    Nomic is a game in which the rules of the game can be changed as part of the gameplay. It was invented by philosopher Peter Suber, and its gameplay demonstrates that in any system with the power to change its own laws, a situation may arise where the laws become paradoxical or self-contradictory.

    Read more on Wikipedia


    PyNomic

    PyNomic is a Python-based version of Nomic where the game's rules are live, executable code. Gameplay revolves around modifying the game itself by proposing changes directly to its source code. Crucially, this power of self-amendment extends to everything, including the very rules that control how players vote on and pass new proposals, making every aspect of the game mutable.


    Game API Reference

    The following functions and variables are available to be used within the game rules:

    Core Globals & Functions
    • game_state: A dictionary containing all persistent data about the current game, like scores and player lists. This is saved to the database at the end of a successful turn.
    • game_secrets: A dictionary for storing hidden information. This is saved between turns but is not visible to players on the "View State" screen.
    • game_state['player_can_move']: A list of players who are able to move. The server will allow any of these players to execute Rule 0. No other player may start a turn during another player's turn.
    • rules: A dictionary where keys are integer rule IDs and values are the Python code for that rule. Changes to this dictionary are saved at the end of a successful turn. rules[0] will be run as the entry point of every turn.
    • current_player: A string containing the username of the player whose turn is currently being executed.
    • print(message, code=False, diff_with=None): Prints output to the game's terminal. If code=True, it's formatted as code. If `diff_with` is provided with the original code, it will render a side-by-side diff view of the changes.
    • input(prompt, input_type='single_line', initial_value=''): Prompts the current player for input. input_type can be 'single_line', 'multi_line', or 'code'. The initial_value will pre-populate the input field.
    • input_choices(text, choices): Prompts the player with the `text` and displays a button for each string in the `choices` list. Returns the string of the selected choice.
    • end_turn(): Raises a TurnComplete exception. Immediately and successfully ends the current player's turn. Any changes made to game_state or rules will be saved.
    • cancel_turn(): Raises a TurnCancel exception. Immediately cancels the current player's turn. **No changes to game_state or rules will be saved.** This is useful for aborting a turn after an invalid player input.
    • end_game(winners=[]): Ends the game. Sets the winners in the game state and raises a SystemExit exception. Any changes made to game_state or rules will be saved. The winners parameter should be a list of winning player names (e.g., ['Player1']) or an empty list [] for a draw.
    Available Standard Library Modules
    • random: The standard Python module for generating random numbers (e.g., `random.randint(1, 6)`).
    • re: The standard Python module for regular expressions.
    • collections: Provides access to specialized container datatypes like `defaultdict` and `Counter`.
    • math: Provides access to mathematical functions like `math.sqrt()`.
    • datetime: Allows for working with dates and times.
    • traceback: Can be used to print detailed error information, e.g., `traceback.print_exc()`.
    Allowed Built-in Functions & Types
    • Most common, safe built-in functions are available, including: int(), str(), len(), sorted(), list(), dict(), sum(), range(), isinstance(), abs().
    • The exec() and compile() functions are available to allow for rules that execute other rules or code.
    • The standard Exception and SystemExit types are available for use in try...except blocks. Custom exceptions TurnComplete and TurnCancel are also available.

    Vibecoding with LLMs

    You don't need to be a programmer to play PyNomic, you can use a Large Language Model (LLM) like Gemini, Claude, or ChatGPT to write the code for you.

    How to Participate:
    1. Have an Idea: Think about what you want to change. Do you want to give a player extra points? Reverse the turn order? Make a rule that penalizes players for using the letter 'e'? The possibilities are endless.
    2. Write a Prompt: Open your favorite LLM and write a detailed prompt. The key is to provide as much context as possible. You should always include the Game API Reference and the current rules of the game.
    3. Copy and Propose: Once the LLM gives you the Python code for your new rule, copy it and propose it in the game.

    Check in with the LLM about rule changes that other players propose. Ask how the rules might be exploited by a player in order to win.

    Example Prompt:

    Here is a template you can use to get started.

    You are an expert Python programmer helping me play a game called PyNomic, where the rules are Python code. I need to propose a new rule.
    
    Here is the context you need:
    
    **1. The Game API:**
    (Paste the Game API from above.)
    
    **2. The Current Rules of the Game:**
    (Paste the current rules from the "View State" screen in the game lobby.)
    
    **3. The Current State of the Game:**
    (Paste the current game state from the "View State" screen in the game lobby.)
    
    **4. My Idea for a New Rule:**
    I want to create a new rule with ID 100 called "Generosity". This rule should check if the current player's score is over 50. If it is, they must give 10 of their points to the player with the lowest score. You should print a message announcing who gave points to whom. If multiple players are tied for the lowest score, just pick the first one in the `game_state['players']` list.
    
    Please write the complete Python code for this new rule. The code must be a self-contained block that can be executed.

    Initial Ruleset

    Loading...